diff --git a/libs/model.h b/libs/model.h index c0318ac..dece52f 100644 --- a/libs/model.h +++ b/libs/model.h @@ -173,6 +173,14 @@ enum fpga_tile_type #define CENTER_X_PLUS_1 1 // routing col adjacent to center #define CENTER_X_PLUS_2 2 // logic col adjacent to center + +#define CENTER_Y_PLUS_1 1 +#define CENTER_Y_PLUS_2 2 +#define CENTER_Y_MINUS_1 1 +#define CENTER_Y_MINUS_2 2 +#define CENTER_Y_MINUS_3 3 +#define CENTER_Y_MINUS_4 4 + #define CENTER_TOP_IOB_O 3 // deduct from center_y #define CENTER_BOT_IOB_O 1 // add to center_y @@ -850,33 +858,9 @@ int add_conn_range(struct fpga_model* model, add_conn_f add_conn_func, int y1, int x1, const char* name1, int start1, int last1, int y2, int x2, const char* name2, int start2); -// COUNT_DOWN can be OR'ed to start_count to make -// the enumerated wires count from start_count down. -#define COUNT_DOWN 0x100 -#define COUNT_MASK 0xFF - -struct w_point // wire point -{ - const char* name; - int start_count; // if there is a %i in the name, this is the start number - int y, x; -}; - -#define NO_INCREMENT 0 - -#define MAX_NET_POINTS 128 - -struct w_net -{ - // if !last_inc, no incrementing will happen (NO_INCREMENT) - // if last_inc > 0, incrementing will happen to - // the %i in the name from pt.start_count:last_inc - int last_inc; - int num_pts; - struct w_point pt[MAX_NET_POINTS]; -}; - -int add_conn_net(struct fpga_model* model, add_conn_f add_conn_func, const struct w_net *net); +// +// switches +// int add_switch(struct fpga_model* model, int y, int x, const char* from, const char* to, int is_bidirectional); @@ -1002,6 +986,20 @@ enum wire_type wire_to_len(enum wire_type w, int first_len); #define DIR_N3 0x200 #define DIR_FLAGS (DIR_BEG|DIR_S0|DIR_N3) +// some more direction-related macros mostly to make code +// more readable and not directly related to enum extra_wires. +#define DIR_IN 0 +#define DIR_OUT 1 + +#define DIR_POS +1 +#define DIR_NEG -1 +#define DIR_LEFT DIR_NEG +#define DIR_RIGHT DIR_POS +#define DIR_UP DIR_NEG +#define DIR_DOWN DIR_POS + +enum { DIR_NORTH = 0, DIR_EAST, DIR_SOUTH, DIR_WEST }; + // The extra wires must not overlap with logicin_wire or logicout_wire // namespaces so that they can be combined with either of them. enum extra_wires { @@ -1037,7 +1035,10 @@ enum extra_wires { CKPIN, CLK_FEEDBACK, CLK_INDIRECT, - VCC_WIRE = 150, + CFB0, CFB1, CFB2, CFB3, CFB4, CFB5, CFB6, CFB7, + CFB8, CFB9, CFB10, CFB11, CFB12, CFB13, CFB14, CFB15, + DFB0, DFB1, DFB2, DFB3, DFB4, DFB5, DFB6, DFB7, + VCC_WIRE, GND_WIRE, GCLK0 = 200, GCLK1, GCLK2, GCLK3, GCLK4, GCLK5, GCLK6, GCLK7, GCLK8, GCLK9, GCLK10, GCLK11, GCLK12, GCLK13, GCLK14, GCLK15, @@ -1064,6 +1065,8 @@ enum extra_wires { MW_LAST = 3499, }; +const char *fpga_connpt_str(struct fpga_model *model, enum extra_wires wire, + int y, int x, int dest_y, int dest_x); const char* fpga_wire2str(enum extra_wires wire); str16_t fpga_wire2str_i(struct fpga_model* model, enum extra_wires wire); enum extra_wires fpga_str2wire(const char* str); @@ -1079,3 +1082,51 @@ int fdev_is_bram8_outwire(int bo_wire); // direct BO_ value void fdev_macc_inbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_62); void fdev_macc_outbit(enum extra_wires wire, int* tile0_to_3, int* wire0_to_23); + +// +// integer-based net (w_net_i) +// + +struct w_yx { int y, x; }; +#define MAX_NET_I_YX 128 + +struct w_net_i +{ + enum extra_wires wire; + int wire_inc; // 0 = no-inc, 1 = wire+0 and wire+1, etc. + int num_yx; + struct w_yx yx[MAX_NET_I_YX]; +}; + +int add_conn_net_i(struct fpga_model *model, const struct w_net_i *net); + +// +// string-based net (w_net) +// + +// COUNT_DOWN can be OR'ed to start_count to make +// the enumerated wires count from start_count down. +#define COUNT_DOWN 0x100 +#define COUNT_MASK 0xFF + +struct w_point // wire point +{ + const char* name; + int start_count; // if there is a %i in the name, this is the start number + int y, x; +}; + +#define NO_INCREMENT 0 +#define MAX_NET_POINTS 128 + +struct w_net +{ + // if !last_inc, no incrementing will happen (NO_INCREMENT) + // if last_inc > 0, incrementing will happen to + // the %i in the name from pt.start_count:last_inc + int last_inc; + int num_pts; + struct w_point pt[MAX_NET_POINTS]; +}; + +int add_conn_net(struct fpga_model* model, add_conn_f add_conn_func, const struct w_net *net); diff --git a/libs/model_conns.c b/libs/model_conns.c index afdd6ab..aca35bd 100644 --- a/libs/model_conns.c +++ b/libs/model_conns.c @@ -62,18 +62,271 @@ fail: return rc; } -static int cfb_dfb(struct fpga_model *model) +int add_conn_net_i(struct fpga_model *model, const struct w_net_i *net) { - int rc; + int i, j, k, rc; + char i_str[MAX_WIRENAME_LEN], j_str[MAX_WIRENAME_LEN]; + + CHECK_RC(model); + if (net->num_yx < 2) FAIL(EINVAL); + for (i = 0; i < net->num_yx; i++) { + for (j = i+1; j < net->num_yx; j++) { + if (net->yx[j].y == net->yx[i].y + && net->yx[j].x == net->yx[i].x) + continue; + for (k = 0; k <= net->wire_inc; k++) { + snprintf(i_str, sizeof(i_str), fpga_connpt_str(model, net->wire+k, net->yx[i].y, net->yx[i].x, net->yx[j].y, net->yx[j].x)); + snprintf(j_str, sizeof(j_str), fpga_connpt_str(model, net->wire+k, net->yx[j].y, net->yx[j].x, net->yx[i].y, net->yx[i].x)); + if (!i_str[0] || !j_str[0]) FAIL(EINVAL); + if ((rc = add_conn_bi(model, + net->yx[i].y, net->yx[i].x, i_str, + net->yx[j].y, net->yx[j].x, j_str))) FAIL(rc); + } + } + } return 0; fail: return rc; } -#define DIR_LEFT -1 -#define DIR_RIGHT +1 -#define DIR_UP -1 -#define DIR_DOWN +1 +static void net_mirror_y(struct fpga_model *model, struct w_net_i *net) +{ + int i; + for (i = 0; i < net->num_yx; i++) + net->yx[i].y = model->y_height - 1 - net->yx[i].y; +} + +static void net_mirror_x(struct fpga_model *model, struct w_net_i *net) +{ + int i; + for (i = 0; i < net->num_yx; i++) + net->yx[i].x = model->x_width - 1 - net->yx[i].x; +} + +static int cfb_dfb(struct fpga_model *model) +{ + CHECK_RC(model); + + // + // left side of top and bottom center + // + + // top term + { struct w_net_i n = { .wire = CFB0, .wire_inc = 3, .num_yx = 3, + {{ .y = TOP_OUTER_ROW, .x = model->center_x-CENTER_CMTPLL_O }, + { .y = TOP_INNER_ROW, .x = model->center_x-CENTER_CMTPLL_O }, + { .y = TOP_INNER_ROW, .x = model->center_x-CENTER_LOGIC_O }}}; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); + + // bottom term + net_mirror_y(model, &n); + n.wire = CFB4; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); } + + // top into outer io + { struct w_net_i n = { .wire = CFB0, .wire_inc = 1, .num_yx = 2, + {{ .y = TOP_INNER_ROW, .x = model->center_x-CENTER_LOGIC_O }, + { .y = TOP_OUTER_IO, .x = model->center_x-CENTER_LOGIC_O }}}; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); + + // bottom into outer io + net_mirror_y(model, &n); + n.wire = CFB4; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); } + + // top into inner io + { struct w_net_i n = { .wire = CFB2, .wire_inc = 1, .num_yx = 3, + {{ .y = TOP_INNER_ROW, .x = model->center_x-CENTER_LOGIC_O }, + { .y = TOP_OUTER_IO, .x = model->center_x-CENTER_LOGIC_O }, + { .y = TOP_INNER_IO, .x = model->center_x-CENTER_LOGIC_O }}}; + add_conn_net_i(model, &n); + n.wire = CFB10; + add_conn_net_i(model, &n); + + // bottom into inner io + net_mirror_y(model, &n); + n.wire = CFB6; + add_conn_net_i(model, &n); + n.wire = CFB14; + add_conn_net_i(model, &n); } + + // + // right side of top and bottom center + // + + // top term + { struct w_net_i n = { .wire = CFB4, .wire_inc = 3, .num_yx = 5, + {{ .y = TOP_OUTER_ROW, .x = model->center_x-CENTER_CMTPLL_O }, + { .y = TOP_INNER_ROW, .x = model->center_x-CENTER_CMTPLL_O }, + { .y = TOP_INNER_ROW, .x = model->center_x }, + { .y = TOP_INNER_ROW, .x = model->center_x+CENTER_X_PLUS_1 }, + { .y = TOP_INNER_ROW, .x = model->center_x+CENTER_X_PLUS_2 }}}; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); + + // bottom term + net_mirror_y(model, &n); + n.wire = CFB0; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); } + + // top into outer io + { struct w_net_i n = { .wire = CFB4, .wire_inc = 1, .num_yx = 2, + {{ .y = TOP_INNER_ROW, .x = model->center_x+CENTER_X_PLUS_2 }, + { .y = TOP_OUTER_IO, .x = model->center_x+CENTER_X_PLUS_2 }}}; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); + + // bottom into outer io + net_mirror_y(model, &n); + n.wire = CFB0; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); } + + // top into inner io + { struct w_net_i n = { .wire = CFB6, .wire_inc = 1, .num_yx = 3, + {{ .y = TOP_INNER_ROW, .x = model->center_x+CENTER_X_PLUS_2 }, + { .y = TOP_OUTER_IO, .x = model->center_x+CENTER_X_PLUS_2 }, + { .y = TOP_INNER_IO, .x = model->center_x+CENTER_X_PLUS_2 }}}; + add_conn_net_i(model, &n); + n.wire = CFB14; + add_conn_net_i(model, &n); + + // bottom into inner io + net_mirror_y(model, &n); + n.wire = CFB2; + add_conn_net_i(model, &n); + n.wire = CFB10; + add_conn_net_i(model, &n); } + + // + // left and right center + + // term: bottom side left center + { struct w_net_i n = { .wire = CFB0, .wire_inc = 1, .num_yx = 4, + {{ .y = model->center_y, .x = LEFT_OUTER_COL }, + { .y = model->center_y, .x = LEFT_INNER_COL }, + { .y = model->center_y + CENTER_Y_PLUS_1, .x = LEFT_INNER_COL }, + { .y = model->center_y + CENTER_Y_PLUS_2, .x = LEFT_INNER_COL }}}; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); + n.num_yx--; // one less - remove CENTER_Y_PLUS_2 + n.wire = CFB2; + add_conn_net_i(model, &n); + n.wire = CFB10; + add_conn_net_i(model, &n); + + // term: bottom side right center + n.num_yx++; + net_mirror_x(model, &n); + + n.wire = CFB6; + add_conn_net_i(model, &n); + n.wire = CFB14; + add_conn_net_i(model, &n); + n.num_yx--; // one less - remove CENTER_Y_PLUS_2 + n.wire = CFB4; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); } + + // term: top side left center + { struct w_net_i n = { .wire = CFB6, .wire_inc = 1, .num_yx = 6, + {{ .y = model->center_y, .x = LEFT_OUTER_COL }, + { .y = model->center_y, .x = LEFT_INNER_COL }, + { .y = model->center_y - CENTER_Y_MINUS_1, .x = LEFT_INNER_COL }, + { .y = model->center_y - CENTER_Y_MINUS_2, .x = LEFT_INNER_COL }, + { .y = model->center_y - CENTER_Y_MINUS_3, .x = LEFT_INNER_COL }, + { .y = model->center_y - CENTER_Y_MINUS_4, .x = LEFT_INNER_COL }}}; + add_conn_net_i(model, &n); + n.wire = CFB14; + add_conn_net_i(model, &n); + n.num_yx--; // one less - remove CENTER_Y_MINUS_4 + n.wire = CFB4; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); + + // term: top side right center + n.num_yx++; + net_mirror_x(model, &n); + n.wire = CFB0; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); + n.num_yx--; // one less - remove CENTER_Y_MINUS_4 + n.wire = CFB2; + add_conn_net_i(model, &n); + n.wire = CFB10; + add_conn_net_i(model, &n); } + + // io devs: left + { struct w_net_i n = { .wire = CFB0, .wire_inc = 1, .num_yx = 3, + {{ .y = model->center_y + CENTER_Y_PLUS_2, .x = LEFT_INNER_COL }, + { .y = model->center_y + CENTER_Y_PLUS_2, .x = LEFT_IO_ROUTING }, + { .y = model->center_y + CENTER_Y_PLUS_2, .x = LEFT_IO_DEVS }}}; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); + + n.wire = CFB2; + n.yx[0].y = n.yx[1].y = n.yx[2].y = model->center_y + CENTER_Y_PLUS_1; + add_conn_net_i(model, &n); + n.wire = CFB10; + add_conn_net_i(model, &n); + + n.wire = CFB4; + n.yx[0].y = n.yx[1].y = n.yx[2].y = model->center_y - CENTER_Y_MINUS_3; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); + + n.wire = CFB6; + n.yx[0].y = n.yx[1].y = n.yx[2].y = model->center_y - CENTER_Y_MINUS_4; + add_conn_net_i(model, &n); + n.wire = CFB14; + add_conn_net_i(model, &n); } + + // io devs: right + { struct w_net_i n = { .wire = CFB0, .wire_inc = 1, .num_yx = 2, + {{ .y = model->center_y - CENTER_Y_MINUS_4, .x = model->x_width - RIGHT_INNER_O }, + { .y = model->center_y - CENTER_Y_MINUS_4, .x = model->x_width - RIGHT_IO_DEVS_O }}}; + add_conn_net_i(model, &n); + n.wire = CFB8; + add_conn_net_i(model, &n); + + n.wire = CFB2; + n.yx[0].y = n.yx[1].y = model->center_y - CENTER_Y_MINUS_3; + add_conn_net_i(model, &n); + n.wire = CFB10; + add_conn_net_i(model, &n); + + n.wire = CFB4; + n.yx[0].y = n.yx[1].y = model->center_y + CENTER_Y_PLUS_1; + add_conn_net_i(model, &n); + n.wire = CFB12; + add_conn_net_i(model, &n); + + n.wire = CFB6; + n.yx[0].y = n.yx[1].y = model->center_y + CENTER_Y_PLUS_2; + add_conn_net_i(model, &n); + n.wire = CFB14; + add_conn_net_i(model, &n); } + return 0; +} static int pcice_ew(struct fpga_model *model, int y); static int pcice_ew_run(struct fpga_model *model, int y, int start_x, int x_dir); diff --git a/libs/model_helper.c b/libs/model_helper.c index 3ce9a71..0235091 100644 --- a/libs/model_helper.c +++ b/libs/model_helper.c @@ -837,35 +837,289 @@ const char* logicout_str(enum logicout_wire w) return 0; } +const char *fpga_connpt_str(struct fpga_model *model, enum extra_wires wire, + int y, int x, int dest_y, int dest_x) +{ + enum { NUM_BUFS = 8, BUF_SIZE = MAX_WIRENAME_LEN }; + static char buf[NUM_BUFS][BUF_SIZE]; + static int last_buf = 0; + + last_buf = (last_buf+1)%NUM_BUFS; + buf[last_buf][0] = 0; + + if (wire >= CFB0 && wire <= CFB15) { + if (is_aty(Y_OUTER_TOP, model, y)) { + if (is_atx(X_CENTER_CMTPLL_COL, model, x)) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGT_%s", fpga_wire2str(wire)); + else HERE(); + } else if (is_aty(Y_INNER_TOP, model, y)) { + if (is_atx(X_CENTER_LOGIC_COL, model, x)) { + if ((wire >= CFB0 && wire <= CFB3) + || (wire >= CFB8 && wire <= CFB11)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_REGT_CFB%s_%c%i", + wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M', + ((wire-CFB0)%4)/2+1); + if (is_atyx(YX_DEV_ILOGIC, model, dest_y, dest_x)) + strcat(buf[last_buf], "_S"); + } else HERE(); + } else if (is_atx(X_CENTER_CMTPLL_COL, model, x)) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGT_TTERM_%s", fpga_wire2str(wire)); + else if (is_atx(X_CENTER_REGS_COL, model, x)) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGV_TTERM_%s", fpga_wire2str(wire)); + else if (x == model->center_x + CENTER_X_PLUS_1) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_TTERM_%s", fpga_wire2str(wire)); + else if (x == model->center_x + CENTER_X_PLUS_2) { + if ((wire >= CFB4 && wire <= CFB7) + || (wire >= CFB12 && wire <= CFB15)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_REGT_CFB%s_%c%i", + wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M', + ((wire-CFB0)%4)/2+1); + if (is_atyx(YX_DEV_ILOGIC, model, dest_y, dest_x)) + strcat(buf[last_buf], "_S"); + } else HERE(); + } else HERE(); + } else if (is_aty(Y_TOP_OUTER_IO, model, y)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "TIOI_%s_CFB%s_%c%s", + (wire-CFB0)%4 < 2 ? "OUTER" : "INNER", + wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M', + ((wire-CFB0)%4)/2 ? "_EXT" : ""); + } else if (is_aty(Y_TOP_INNER_IO, model, y)) { + if ((wire-CFB0)%4 >= 2) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "TIOI_INNER_CFB%s_%c", + wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M'); + } else HERE(); + } else if (is_aty(Y_BOT_INNER_IO, model, y)) { + if ((wire-CFB0)%4 >= 2) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "BIOI_INNER_CFB%s_%c", + wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M'); + } else HERE(); + } else if (is_aty(Y_BOT_OUTER_IO, model, y)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "BIOI_%s_CFB%s_%c%s", + (wire-CFB0)%4 < 2 ? "OUTER" : "INNER", + wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M', + ((wire-CFB0)%4)/2 ? "_EXT" : ""); + } else if (is_aty(Y_INNER_BOTTOM, model, y)) { + if (is_atx(X_CENTER_LOGIC_COL, model, x)) { + if ((wire >= CFB4 && wire <= CFB7) + || (wire >= CFB12 && wire <= CFB15)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "BTERM_CLB_%s", fpga_wire2str(wire)); + if (is_atyx(YX_DEV_ILOGIC, model, dest_y, dest_x)) + strcat(buf[last_buf], "_N"); + } else HERE(); + } else if (is_atx(X_CENTER_CMTPLL_COL, model, x)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGB_BTERM_%s", fpga_wire2str(wire)); + } else if (is_atx(X_CENTER_REGS_COL, model, x)) { + if ((wire >= CFB0 && wire <= CFB3) + || (wire >= CFB8 && wire <= CFB11)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGV_BTERM_%s", fpga_wire2str(wire+4)); + } else HERE(); + } else if (x == model->center_x + CENTER_X_PLUS_1) { + if (wire >= CFB0 && wire <= CFB3) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_BTERM_%s", fpga_wire2str(wire+4)); + else if (wire >= CFB8 && wire <= CFB11) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_BTERM_BUFPLL_%s", fpga_wire2str(wire+4)); + else HERE(); + } else if (x == model->center_x + CENTER_X_PLUS_2) { + if ((wire >= CFB0 && wire <= CFB3) + || (wire >= CFB8 && wire <= CFB11)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "BTERM_CLB_%s", fpga_wire2str(wire+4)); + if (is_atyx(YX_DEV_ILOGIC, model, dest_y, dest_x)) + strcat(buf[last_buf], "_N"); + } else HERE(); + } else HERE(); + } else if (is_aty(Y_OUTER_BOTTOM, model, y)) { + if (is_atx(X_CENTER_CMTPLL_COL, model, x)) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGB_%s", fpga_wire2str(wire)); + else HERE(); + } else if (is_atx(X_OUTER_LEFT, model, x)) { + if (is_aty(Y_CHIP_HORIZ_REGS, model, y)) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGL_%s", fpga_wire2str(wire)); + else HERE(); + } else if (is_atx(X_INNER_LEFT, model, x)) { + if (is_aty(Y_CHIP_HORIZ_REGS, model, y)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGH_LTERM_%s", fpga_wire2str(wire)); + } else if (y == model->center_y + CENTER_Y_PLUS_1) { + if ((wire-CFB0)%8 < 4) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_LTERM_TOP_%s", fpga_wire2str(wire)); + if (is_atx(X_LEFT_IO_ROUTING_COL|X_LEFT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_E"); + } else HERE(); + } else if (y == model->center_y + CENTER_Y_PLUS_2) { + if ((wire-CFB0)%8 < 2) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_LTERM_BOT_%s", fpga_wire2str(wire)); + if (is_atx(X_LEFT_IO_ROUTING_COL|X_LEFT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_E"); + } else HERE(); + } else if (y == model->center_y - CENTER_Y_MINUS_1 + || y == model->center_y - CENTER_Y_MINUS_2) { + if ((wire-CFB0)%8 >= 4) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_LTERM_%s_EXT", fpga_wire2str(wire-4)); + else HERE(); + } else if (y == model->center_y - CENTER_Y_MINUS_3) { + if ((wire-CFB0)%8 >= 4) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_LTERM_BOT_%s", fpga_wire2str(wire-4)); + if (is_atx(X_LEFT_IO_ROUTING_COL|X_LEFT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_E"); + } else HERE(); + } else if (y == model->center_y - CENTER_Y_MINUS_4) { + if ((wire-CFB0)%8 >= 4) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_LTERM_TOP_%s", fpga_wire2str(wire-4)); + if (is_atx(X_LEFT_IO_ROUTING_COL|X_LEFT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_E"); + } else HERE(); + } else HERE(); + } else if (is_atx(X_LEFT_IO_ROUTING_COL, model, x)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "INT_CFB%s_%c", wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M'); + } else if (is_atx(X_LEFT_IO_DEVS_COL, model, x)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "LIOI_CFB%s_%c_ILOGIC", wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M'); + } else if (is_atx(X_RIGHT_IO_DEVS_COL, model, x)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "RIOI_CFB%s_%c_ILOGIC", wire >= CFB8 ? "1" : "", + (wire-CFB0) % 2 ? 'S' : 'M'); + } else if (is_atx(X_INNER_RIGHT, model, x)) { + if (is_aty(Y_CHIP_HORIZ_REGS, model, y)) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGH_RTERM_%s", fpga_wire2str(wire)); + } else if (y == model->center_y + CENTER_Y_PLUS_1) { + if ((wire-CFB0)%8 >= 4) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_RTERM_TOP_%s", fpga_wire2str(wire-4)); + if (is_atx(X_RIGHT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_W"); + } else HERE(); + } else if (y == model->center_y + CENTER_Y_PLUS_2) { + if ((wire-CFB0)%8 >= 6) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_RTERM_BOT_%s", fpga_wire2str(wire-4)); + if (is_atx(X_RIGHT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_W"); + } else HERE(); + } else if (y == model->center_y - CENTER_Y_MINUS_1 + || y == model->center_y - CENTER_Y_MINUS_2) { + if ((wire-CFB0)%8 < 4) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_RTERM_%s%s", fpga_wire2str(wire), + wire < CFB8 ? "_EXT" : ""); + else HERE(); + } else if (y == model->center_y - CENTER_Y_MINUS_3) { + if ((wire-CFB0)%8 < 4) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_RTERM_BOT_%s", fpga_wire2str(wire)); + if (is_atx(X_RIGHT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_W"); + } else HERE(); + } else if (y == model->center_y - CENTER_Y_MINUS_4) { + if ((wire-CFB0)%8 < 4) { + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "IOI_RTERM_TOP_%s", fpga_wire2str(wire)); + if (is_atx(X_RIGHT_IO_DEVS_COL, model, dest_x)) + strcat(buf[last_buf], "_W"); + } else HERE(); + } else HERE(); + } else if (is_atx(X_OUTER_RIGHT, model, x)) { + if (is_aty(Y_CHIP_HORIZ_REGS, model, y)) + snprintf(buf[last_buf], sizeof(buf[last_buf]), + "REGR_%s", fpga_wire2str(wire)); + else HERE(); + } else HERE(); + } else HERE(); + return buf[last_buf]; +} + const char* fpga_wire2str(enum extra_wires wire) { - enum { NUM_BUFS = 8, BUF_SIZE = 64 }; + enum { NUM_BUFS = 8, BUF_SIZE = MAX_WIRENAME_LEN }; static char buf[NUM_BUFS][BUF_SIZE]; static int last_buf = 0; int flags; switch (wire) { - case GFAN0: return "GFAN0"; - case GFAN1: return "GFAN1"; - case CLK0: return "CLK0"; - case CLK1: return "CLK1"; - case SR0: return "SR0"; - case SR1: return "SR1"; - case GND_WIRE: return "GND_WIRE"; - case VCC_WIRE: return "VCC_WIRE"; - case FAN_B: return "FAN_B"; - case LOGICIN20: return "LOGICIN20"; - case LOGICIN21: return "LOGICIN21"; - case LOGICIN44: return "LOGICIN44"; - case LOGICIN52: return "LOGICIN52"; - case LOGICIN_N21: return "LOGICIN_N21"; - case LOGICIN_N28: return "LOGICIN_N28"; - case LOGICIN_N52: return "LOGICIN_N52"; - case LOGICIN_N60: return "LOGICIN_N60"; - case LOGICIN_S20: return "LOGICIN_S20"; - case LOGICIN_S36: return "LOGICIN_S36"; - case LOGICIN_S44: return "LOGICIN_S44"; - case LOGICIN_S62: return "LOGICIN_S62"; + case GFAN0: return "GFAN0"; + case GFAN1: return "GFAN1"; + case CLK0: return "CLK0"; + case CLK1: return "CLK1"; + case SR0: return "SR0"; + case SR1: return "SR1"; + case GND_WIRE: return "GND_WIRE"; + case VCC_WIRE: return "VCC_WIRE"; + case FAN_B: return "FAN_B"; + case LOGICIN20: return "LOGICIN20"; + case LOGICIN21: return "LOGICIN21"; + case LOGICIN44: return "LOGICIN44"; + case LOGICIN52: return "LOGICIN52"; + case LOGICIN_N21: return "LOGICIN_N21"; + case LOGICIN_N28: return "LOGICIN_N28"; + case LOGICIN_N52: return "LOGICIN_N52"; + case LOGICIN_N60: return "LOGICIN_N60"; + case LOGICIN_S20: return "LOGICIN_S20"; + case LOGICIN_S36: return "LOGICIN_S36"; + case LOGICIN_S44: return "LOGICIN_S44"; + case LOGICIN_S62: return "LOGICIN_S62"; + case IOCE: return "IOCE"; + case IOCLK: return "IOCLK"; + case PLLCE: return "PLLCE"; + case PLLCLK: return "PLLCLK"; + case CKPIN: return "CKPIN"; + case CLK_FEEDBACK: return "CLK_FEEDBACK"; + case CLK_INDIRECT: return "CLK_INDIRECT"; + case CFB0: return "CFB0"; + case CFB1: return "CFB1"; + case CFB2: return "CFB2"; + case CFB3: return "CFB3"; + case CFB4: return "CFB4"; + case CFB5: return "CFB5"; + case CFB6: return "CFB6"; + case CFB7: return "CFB7"; + case CFB8: return "CFB1_0"; + case CFB9: return "CFB1_1"; + case CFB10: return "CFB1_2"; + case CFB11: return "CFB1_3"; + case CFB12: return "CFB1_4"; + case CFB13: return "CFB1_5"; + case CFB14: return "CFB1_6"; + case CFB15: return "CFB1_7"; + case DFB0: return "DFB0"; + case DFB1: return "DFB1"; + case DFB2: return "DFB2"; + case DFB3: return "DFB3"; + case DFB4: return "DFB4"; + case DFB5: return "DFB5"; + case DFB6: return "DFB6"; + case DFB7: return "DFB7"; default: ; }