From 7c12ea66a7133c7631cb88de629b01217f4eca58 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Thu, 24 Jan 2013 00:38:54 -0500 Subject: [PATCH] improved iologic switches --- autotest.c | 208 +++++++++++++++++++++------------- libs/bit_frames.c | 270 +++++++++++++++++++------------------------- libs/control.c | 5 +- libs/model.h | 18 +++ libs/model_helper.c | 103 +++++++++++++++++ libs/parts.c | 2 +- 6 files changed, 367 insertions(+), 239 deletions(-) diff --git a/autotest.c b/autotest.c index 65125e7..bfbd0fb 100644 --- a/autotest.c +++ b/autotest.c @@ -72,7 +72,7 @@ static int diff_printf(struct test_state* tstate) int rc; if (tstate->cmdline_count != -1 - && tstate->next_diff_counter >= tstate->cmdline_skip + tstate->cmdline_count + 1) { + && tstate->next_diff_counter >= tstate->cmdline_skip + tstate->cmdline_count) { printf("\nO Finished %i tests.\n", tstate->cmdline_count); exit(0); } @@ -709,10 +709,10 @@ fail: static int test_iologic_switches2(struct test_state* tstate, int iob_y, int iob_x, int iob_type_idx) { struct fpga_device* iob_dev; - struct switch_to_yx switch_to; - struct sw_chain chain; + struct sw_conns iob_conns; + struct sw_chain iologic_chain; net_idx_t net_idx; - int i, from_to, rc; + int pin_i, from_to, rc; rc = fdev_set_required_pins(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx); if (rc) FAIL(rc); @@ -721,68 +721,71 @@ static int test_iologic_switches2(struct test_state* tstate, int iob_y, int iob_ iob_dev = fdev_p(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx); if (!iob_dev) FAIL(EINVAL); - for (i = 0; i < iob_dev->pinw_req_total; i++) { - from_to = i >= iob_dev->pinw_req_in ? SW_FROM : SW_TO; + for (pin_i = 0; pin_i < iob_dev->pinw_req_total; pin_i++) { + from_to = pin_i >= iob_dev->pinw_req_in ? SW_FROM : SW_TO; - // determine switch in iob to reach iologic tile - switch_to.yx_req = YX_DEV_ILOGIC; - switch_to.flags = SWTO_YX_DEF; - switch_to.model = tstate->model; - switch_to.y = iob_y; - switch_to.x = iob_x; - switch_to.start_switch = iob_dev->pinw[iob_dev->pinw_req_for_cfg[i]]; - switch_to.from_to = from_to; - switch_to.exclusive_net = NO_NET; - rc = fpga_switch_to_yx(&switch_to); - if (rc) FAIL(rc); - if (tstate->dry_run) - printf_switch_to_yx_result(&switch_to); - - if (construct_sw_chain(&chain, tstate->model, switch_to.dest_y, - switch_to.dest_x, switch_to.dest_connpt, from_to, - /*max_depth*/ -1, NO_NET, /*block_list*/ 0, /*block_list_len*/ 0)) - FAIL(EINVAL); - while (fpga_switch_chain(&chain) != NO_CONN) { - - if (tstate->dry_run) - printf("sw %s\n", fmt_swset(tstate->model, - switch_to.dest_y, switch_to.dest_x, - &chain.set, from_to)); - - // new net - rc = fnet_new(tstate->model, &net_idx); - if (rc) FAIL(rc); - - // add iob port - rc = fnet_add_port(tstate->model, net_idx, iob_y, iob_x, - DEV_IOB, iob_type_idx, IOB_IN_O); - if (rc) FAIL(rc); - - // add switch in iob tile - rc = fnet_add_sw(tstate->model, net_idx, switch_to.y, - switch_to.x, switch_to.set.sw, switch_to.set.len); - if (rc) FAIL(rc); - - // add all but last switch in set - if (chain.set.len > 1) { - rc = fnet_add_sw(tstate->model, net_idx, switch_to.dest_y, - switch_to.dest_x, chain.set.sw, chain.set.len-1); - if (rc) FAIL(rc); + construct_sw_conns(&iob_conns, tstate->model, iob_y, iob_x, + iob_dev->pinw[iob_dev->pinw_req_for_cfg[pin_i]], + from_to, SW_SET_SIZE, NO_NET); + RC_CHECK(tstate->model); + while (fpga_switch_conns(&iob_conns) != NO_CONN) { + if (!is_atyx(YX_DEV_ILOGIC, tstate->model, iob_conns.dest_y, iob_conns.dest_x)) + continue; + if (tstate->dry_run) { + printf(" sw %s conn y%i x%i %s\n", + fmt_swset(tstate->model, iob_y, iob_x, + &iob_conns.chain.set, from_to), + iob_conns.dest_y, iob_conns.dest_x, + strarray_lookup(&tstate->model->str, iob_conns.dest_str_i)); } - rc = diff_printf(tstate); - if (rc) FAIL(rc); + + if (construct_sw_chain(&iologic_chain, tstate->model, iob_conns.dest_y, + iob_conns.dest_x, iob_conns.dest_str_i, from_to, + /*max_depth*/ -1, NO_NET, /*block_list*/ 0, /*block_list_len*/ 0)) + FAIL(EINVAL); + while (fpga_switch_chain(&iologic_chain) != NO_CONN) { - // add last switch - rc = fnet_add_sw(tstate->model, net_idx, switch_to.dest_y, - switch_to.dest_x, &chain.set.sw[chain.set.len-1], 1); - if (rc) FAIL(rc); + if (tstate->dry_run) + printf("sw %s\n", fmt_swset(tstate->model, + iologic_chain.y, iologic_chain.x, + &iologic_chain.set, iologic_chain.from_to)); - rc = diff_printf(tstate); - if (rc) FAIL(rc); + // new net + rc = fnet_new(tstate->model, &net_idx); + if (rc) FAIL(rc); - fnet_delete(tstate->model, net_idx); + // add iob port + rc = fnet_add_port(tstate->model, net_idx, iob_y, iob_x, + DEV_IOB, iob_type_idx, IOB_IN_O); + if (rc) FAIL(rc); + + // add switch in iob tile + rc = fnet_add_sw(tstate->model, net_idx, iob_y, + iob_x, iob_conns.chain.set.sw, iob_conns.chain.set.len); + if (rc) FAIL(rc); + + // add all but last switch in set + if (iologic_chain.set.len > 1) { + rc = fnet_add_sw(tstate->model, net_idx, iologic_chain.y, + iologic_chain.x, iologic_chain.set.sw, iologic_chain.set.len-1); + if (rc) FAIL(rc); + } + rc = diff_printf(tstate); + if (rc) FAIL(rc); + + // add last switch + rc = fnet_add_sw(tstate->model, net_idx, iologic_chain.y, + iologic_chain.x, &iologic_chain.set.sw[iologic_chain.set.len-1], 1); + if (rc) FAIL(rc); + + rc = diff_printf(tstate); + if (rc) FAIL(rc); + + fnet_delete(tstate->model, net_idx); + } + destruct_sw_chain(&iologic_chain); } - destruct_sw_chain(&chain); + destruct_sw_conns(&iob_conns); } return 0; fail: @@ -791,29 +794,70 @@ fail: static int test_iologic_switches(struct test_state* tstate) { - char iob_name[32]; - int iob_y, iob_x, iob_type_idx, i, rc; + enum { MAX_IOBS_UNDER_TEST = 16 }; + int iob_y[MAX_IOBS_UNDER_TEST], iob_x[MAX_IOBS_UNDER_TEST]; + int iob_type_idx[MAX_IOBS_UNDER_TEST], iob_pin_i[MAX_IOBS_UNDER_TEST]; + int num_iobs_under_test, test_input; + int bank_i, pin_i, bank_max, cur_bank, i, rc; - for (i = 45; i <= 48; i++) { - snprintf(iob_name, sizeof(iob_name), "P%i", i); + // + // determine IOBs under test + // - // input IOB - rc = fpga_find_iob(tstate->model, iob_name, &iob_y, &iob_x, &iob_type_idx); - if (rc) FAIL(rc); - rc = fdev_iob_input(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33); - if (rc) FAIL(rc); - rc = test_iologic_switches2(tstate, iob_y, iob_x, iob_type_idx); - if (rc) FAIL(rc); - fdev_delete(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx); + num_iobs_under_test = 0; + for (cur_bank = 0; cur_bank <= 3; cur_bank++) { + // bank0: top, take 4 (2 leading to outer, 2 to inner iologic tiles) + // bank1: right, take 2 + // bank2: bottom, take 4 (2 leading to outer, 2 to inner iologic tiles) + // bank3: left, take 2 + bank_max = (!cur_bank || cur_bank == 2) ? 4 : 2; + bank_i = 0; + for (pin_i = 0; pin_i < tstate->model->pkg->num_pins; pin_i++) { + if (tstate->model->pkg->pin[pin_i].bank != cur_bank + || !tstate->model->pkg->pin[pin_i].pair) + continue; - // output IOB - rc = fpga_find_iob(tstate->model, iob_name, &iob_y, &iob_x, &iob_type_idx); - if (rc) FAIL(rc); - rc = fdev_iob_output(tstate->model, iob_y, iob_x, iob_type_idx, IO_LVCMOS33); - if (rc) FAIL(rc); - rc = test_iologic_switches2(tstate, iob_y, iob_x, iob_type_idx); - if (rc) FAIL(rc); - fdev_delete(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx); + rc = fpga_find_iob(tstate->model, + tstate->model->pkg->pin[pin_i].name, + &iob_y[num_iobs_under_test], + &iob_x[num_iobs_under_test], + &iob_type_idx[num_iobs_under_test]); + if (rc) FAIL(rc); + iob_pin_i[num_iobs_under_test] = pin_i; + num_iobs_under_test++; + if (++bank_i >= bank_max) + break; + } + } + + for (test_input = 1;;) { + for (i = 0; i < num_iobs_under_test; i++) { + if (!i || tstate->model->pkg->pin[iob_pin_i[i-1]].bank + != tstate->model->pkg->pin[iob_pin_i[i]].bank) + bank_i = 0; + printf("\nO test %i: IOB %s input - bank %i (#%i) pair %i pos %i " + "bufio2 %s desc %s y%i x%i type_idx %i\n", + tstate->next_diff_counter, + tstate->model->pkg->pin[iob_pin_i[i]].name, + tstate->model->pkg->pin[iob_pin_i[i]].bank, + bank_i, + tstate->model->pkg->pin[iob_pin_i[i]].pair, + tstate->model->pkg->pin[iob_pin_i[i]].pos_side, + tstate->model->pkg->pin[iob_pin_i[i]].bufio2, + tstate->model->pkg->pin[iob_pin_i[i]].description, + iob_y[i], iob_x[i], iob_type_idx[i]); + bank_i++; + + rc = test_input ? + fdev_iob_input(tstate->model, iob_y[i], iob_x[i], iob_type_idx[i], IO_LVCMOS33) + : fdev_iob_output(tstate->model, iob_y[i], iob_x[i], iob_type_idx[i], IO_LVCMOS33); + if (rc) FAIL(rc); + rc = test_iologic_switches2(tstate, iob_y[i], iob_x[i], iob_type_idx[i]); + if (rc) FAIL(rc); + fdev_delete(tstate->model, iob_y[i], iob_x[i], DEV_IOB, iob_type_idx[i]); + } + if (!test_input) break; + test_input = 0; } return 0; fail: @@ -829,6 +873,8 @@ static int test_iob_config(struct test_state* tstate) tstate->diff_to_null = 1; + // todo: has to change to model->pkg names to work with ftg256... + // P45 is an IOBS rc = fpga_find_iob(tstate->model, "P45", &iob_y, &iob_x, &iob_type_idx); if (rc) FAIL(rc); @@ -2005,7 +2051,7 @@ int main(int argc, char** argv) MEMUSAGE(); printf("O Building memory model...\n"); - if ((rc = fpga_build_model(&model, XC6SLX9, TQG144))) + if ((rc = fpga_build_model(&model, XC6SLX9, FTG256))) goto fail; printf("O Done\n"); TIME_AND_MEM(); diff --git a/libs/bit_frames.c b/libs/bit_frames.c index 216bdeb..cefd989 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -1687,156 +1687,108 @@ fail: #define MAX_IOLOGIC_BITS 4 struct iologic_sw_pos { - const char* to[MAX_IOLOGIC_SWBLOCK]; - const char* from[MAX_IOLOGIC_SWBLOCK]; + enum iologic_wire to[MAX_IOLOGIC_SWBLOCK]; + enum iologic_wire from[MAX_IOLOGIC_SWBLOCK]; int minor[MAX_IOLOGIC_BITS]; int b64[MAX_IOLOGIC_BITS]; }; -// todo: can we assume the maximum range for iologic -// minors to be 21..29? that would be a total of -// 9*64=675 bits for ilogic/ologic/iodelay? -struct iologic_sw_pos s_left_io_swpos[] = { {{0}} }; -struct iologic_sw_pos s_right_io_swpos[] = { {{0}} }; -struct iologic_sw_pos s_top_outer_io_swpos[] = { {{0}} }; -struct iologic_sw_pos s_top_inner_io_swpos[] = { {{0}} }; - -struct iologic_sw_pos s_bot_inner_io_swpos[] = +struct iologic_sw_pos s_leftright_swpos[] = { // input - {{"D_ILOGIC_IDATAIN_IODELAY_S"}, - {"BIOI_INNER_IBUF0"}, - {23, 23, -1}, + {{D_ILOGIC_IDATAIN_IODELAY_S}, {IBUF0}, + {24, 24, -1}, {28, 29}}, - - {{"D_ILOGIC_SITE"}, - {"D_ILOGIC_IDATAIN_IODELAY"}, - {26, -1}, + {{D_ILOGIC_SITE}, {D_ILOGIC_IDATAIN_IODELAY}, + {29, -1}, {20}}, - - {{"D_ILOGIC_SITE_S"}, - {"D_ILOGIC_IDATAIN_IODELAY_S"}, - {26, -1}, + {{D_ILOGIC_SITE_S}, {D_ILOGIC_IDATAIN_IODELAY_S}, + {29, -1}, {23}}, - - {{"DFB_ILOGIC_SITE"}, - {"D_ILOGIC_SITE"}, + {{DFB_ILOGIC_SITE}, {D_ILOGIC_SITE}, {28, -1}, {63}}, - - {{"DFB_ILOGIC_SITE_S"}, - {"D_ILOGIC_SITE_S"}, + {{DFB_ILOGIC_SITE_S}, {D_ILOGIC_SITE_S}, {28, -1}, {0}}, + {{FABRICOUT_ILOGIC_SITE}, {D_ILOGIC_SITE}, + {23, -1}, + {49}}, + {{FABRICOUT_ILOGIC_SITE_S}, {D_ILOGIC_SITE_S}, + {23, -1}, + {14}}, - {{"FABRICOUT_ILOGIC_SITE"}, - {"D_ILOGIC_SITE"}, + // output + {{OQ_OLOGIC_SITE, O0}, {D1_OLOGIC_SITE, OQ_OLOGIC_SITE}, + {29, 27, 28, -1}, + {40, 21, 57}}, + {{OQ_OLOGIC_SITE_S, O1}, {D1_OLOGIC_SITE_S, OQ_OLOGIC_SITE_S}, + {29, 27, 28, -1}, + {43, 56, 6}}, + + {{IOI_LOGICOUT0}, {IOI_INTER_LOGICOUT0}, {-1}}, + {{IOI_LOGICOUT7}, {IOI_INTER_LOGICOUT7}, {-1}}, + {{IOI_INTER_LOGICOUT0}, {FABRICOUT_ILOGIC_SITE}, {-1}}, + {{IOI_INTER_LOGICOUT7}, {FABRICOUT_ILOGIC_SITE_S}, {-1}}, + {{D_ILOGIC_IDATAIN_IODELAY}, {IBUF0}, {-1}}, + {{D_ILOGIC_IDATAIN_IODELAY_S}, {IBUF1}, {-1}}, + {{D1_OLOGIC_SITE}, {IOI_LOGICIN_B31}, {-1}}, + {{0}} +}; + +struct iologic_sw_pos s_topbot_swpos[] = +{ + // input + {{D_ILOGIC_IDATAIN_IODELAY_S}, {IBUF0}, + {23, 23, -1}, + {28, 29}}, + {{D_ILOGIC_SITE}, {D_ILOGIC_IDATAIN_IODELAY}, + {26, -1}, + {20}}, + {{D_ILOGIC_SITE_S}, {D_ILOGIC_IDATAIN_IODELAY_S}, + {26, -1}, + {23}}, + {{DFB_ILOGIC_SITE}, {D_ILOGIC_SITE}, + {28, -1}, + {63}}, + {{DFB_ILOGIC_SITE_S}, {D_ILOGIC_SITE_S}, + {28, -1}, + {0}}, + {{FABRICOUT_ILOGIC_SITE}, {D_ILOGIC_SITE}, {29, -1}, {49}}, - - {{"FABRICOUT_ILOGIC_SITE_S"}, - {"D_ILOGIC_SITE_S"}, + {{FABRICOUT_ILOGIC_SITE_S}, {D_ILOGIC_SITE_S}, {29, -1}, {14}}, // output - {{"OQ_OLOGIC_SITE", "BIOI_INNER_O0"}, - {"D1_OLOGIC_SITE", "OQ_OLOGIC_SITE"}, + {{OQ_OLOGIC_SITE, O0}, {D1_OLOGIC_SITE, OQ_OLOGIC_SITE}, {26, 27, 28, -1}, {40, 21, 57}}, - - {{"OQ_OLOGIC_SITE_S", "BIOI_INNER_O1"}, - {"D1_OLOGIC_SITE_S", "OQ_OLOGIC_SITE_S"}, + {{OQ_OLOGIC_SITE_S, O1}, {D1_OLOGIC_SITE_S, OQ_OLOGIC_SITE_S}, {26, 27, 28, -1}, {43, 56, 6}}, - {{"IOI_LOGICOUT0"}, {"IOI_INTER_LOGICOUT0"}, {-1}}, - {{"IOI_LOGICOUT7"}, {"IOI_INTER_LOGICOUT7"}, {-1}}, - {{"IOI_INTER_LOGICOUT0"}, {"FABRICOUT_ILOGIC_SITE"}, {-1}}, - {{"IOI_INTER_LOGICOUT7"}, {"FABRICOUT_ILOGIC_SITE_S"}, {-1}}, - {{"D_ILOGIC_IDATAIN_IODELAY"}, {"BIOI_INNER_IBUF0"}, {-1}}, - {{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_INNER_IBUF1"}, {-1}}, - {{"D1_OLOGIC_SITE"}, {"IOI_LOGICINB31"}, {-1}}, + {{IOI_LOGICOUT0}, {IOI_INTER_LOGICOUT0}, {-1}}, + {{IOI_LOGICOUT7}, {IOI_INTER_LOGICOUT7}, {-1}}, + {{IOI_INTER_LOGICOUT0}, {FABRICOUT_ILOGIC_SITE}, {-1}}, + {{IOI_INTER_LOGICOUT7}, {FABRICOUT_ILOGIC_SITE_S}, {-1}}, + {{D_ILOGIC_IDATAIN_IODELAY}, {IBUF0}, {-1}}, + {{D_ILOGIC_IDATAIN_IODELAY_S}, {IBUF1}, {-1}}, + {{D1_OLOGIC_SITE}, {IOI_LOGICIN_B31}, {-1}}, {{0}} }; -struct iologic_sw_pos s_bot_outer_io_swpos[] = +static int add_yx_switch_i(struct extract_state *es, + int y, int x, str16_t from, str16_t to) { - // input - {{"D_ILOGIC_IDATAIN_IODELAY_S"}, - {"BIOI_OUTER_IBUF0"}, - {23, 23, -1}, - {28, 29}}, - - {{"D_ILOGIC_SITE"}, - {"D_ILOGIC_IDATAIN_IODELAY"}, - {26, -1}, - {20}}, - - {{"D_ILOGIC_SITE_S"}, - {"D_ILOGIC_IDATAIN_IODELAY_S"}, - {26, -1}, - {23}}, - - {{"DFB_ILOGIC_SITE"}, - {"D_ILOGIC_SITE"}, - {28, -1}, - {63}}, - - {{"DFB_ILOGIC_SITE_S"}, - {"D_ILOGIC_SITE_S"}, - {28, -1}, - {0}}, - - {{"FABRICOUT_ILOGIC_SITE"}, - {"D_ILOGIC_SITE"}, - {29, -1}, - {49}}, - - {{"FABRICOUT_ILOGIC_SITE_S"}, - {"D_ILOGIC_SITE_S"}, - {29, -1}, - {14}}, - - // output - {{"OQ_OLOGIC_SITE", "BIOI_OUTER_O0"}, - {"D1_OLOGIC_SITE", "OQ_OLOGIC_SITE"}, - {26, 27, 28, -1}, - {40, 21, 57}}, - - {{"OQ_OLOGIC_SITE_S", "BIOI_OUTER_O1"}, - {"D1_OLOGIC_SITE_S", "OQ_OLOGIC_SITE_S"}, - {26, 27, 28, -1}, - {43, 56, 6}}, - - {{"IOI_LOGICOUT0"}, {"IOI_INTER_LOGICOUT0"}, {-1}}, - {{"IOI_LOGICOUT7"}, {"IOI_INTER_LOGICOUT7"}, {-1}}, - {{"IOI_INTER_LOGICOUT0"}, {"FABRICOUT_ILOGIC_SITE"}, {-1}}, - {{"IOI_INTER_LOGICOUT7"}, {"FABRICOUT_ILOGIC_SITE_S"}, {-1}}, - {{"D_ILOGIC_IDATAIN_IODELAY"}, {"BIOI_INNER_IBUF0"}, {-1}}, - {{"D_ILOGIC_IDATAIN_IODELAY_S"}, {"BIOI_INNER_IBUF1"}, {-1}}, - {{"D1_OLOGIC_SITE"}, {"IOI_LOGICINB31"}, {-1}}, - {{0}} -}; - -static int add_yx_switch(struct extract_state *es, - int y, int x, const char *from, const char *to) -{ - str16_t from_str_i, to_str_i; swidx_t sw_idx; RC_CHECK(es->model); - - from_str_i = strarray_find(&es->model->str, from); - to_str_i = strarray_find(&es->model->str, to); - RC_ASSERT(es->model, from_str_i != STRIDX_NO_ENTRY - && to_str_i != STRIDX_NO_ENTRY); - sw_idx = fpga_switch_lookup(es->model, y, x, - from_str_i, to_str_i); - RC_ASSERT(es->model, sw_idx != NO_SWITCH); - - RC_ASSERT(es->model, es->num_yx_pos < MAX_YX_SWITCHES); + from, to); + RC_ASSERT(es->model, sw_idx != NO_SWITCH + && es->num_yx_pos < MAX_YX_SWITCHES); es->yx_pos[es->num_yx_pos].y = y; es->yx_pos[es->num_yx_pos].x = x; es->yx_pos[es->num_yx_pos].idx = sw_idx; @@ -1845,6 +1797,17 @@ static int add_yx_switch(struct extract_state *es, RC_RETURN(es->model); } +static int add_yx_switch(struct extract_state *es, + int y, int x, const char *from, const char *to) +{ + str16_t from_str_i, to_str_i; + + RC_CHECK(es->model); + from_str_i = strarray_find(&es->model->str, from); + to_str_i = strarray_find(&es->model->str, to); + return add_yx_switch_i(es, y, x, from_str_i, to_str_i); +} + static int extract_iologic_switches(struct extract_state* es, int y, int x) { int row_num, row_pos, bit_in_frame, i, j, rc; @@ -1865,18 +1828,15 @@ static int extract_iologic_switches(struct extract_state* es, int y, int x) if (x < LEFT_SIDE_WIDTH) { if (x != LEFT_IO_DEVS) FAIL(EINVAL); - sw_pos = s_left_io_swpos; + sw_pos = s_leftright_swpos; } else if (x >= es->model->x_width-RIGHT_SIDE_WIDTH) { if (x != es->model->x_width - RIGHT_IO_DEVS_O) FAIL(EINVAL); - sw_pos = s_right_io_swpos; - } else if (y == TOP_OUTER_IO) - sw_pos = s_top_outer_io_swpos; - else if (y == TOP_INNER_IO) - sw_pos = s_top_inner_io_swpos; - else if (y == es->model->y_height-BOT_INNER_IO) - sw_pos = s_bot_inner_io_swpos; - else if (y == es->model->y_height-BOT_OUTER_IO) - sw_pos = s_bot_outer_io_swpos; + sw_pos = s_leftright_swpos; + } else if (y == TOP_OUTER_IO + || y == TOP_INNER_IO + || y == es->model->y_height-BOT_INNER_IO + || y == es->model->y_height-BOT_OUTER_IO) + sw_pos = s_topbot_swpos; else FAIL(EINVAL); // Go through switches @@ -1889,7 +1849,9 @@ static int extract_iologic_switches(struct extract_state* es, int y, int x) if (!j || sw_pos[i].minor[j] != -1) continue; for (j = 0; j < MAX_IOLOGIC_SWBLOCK && sw_pos[i].to[j]; j++) - add_yx_switch(es, y, x, sw_pos[i].from[j], sw_pos[i].to[j]); + add_yx_switch_i(es, y, x, + fpga_iologic_wire2str_yx(es->model, sw_pos[i].from[j], y, x), + fpga_iologic_wire2str_yx(es->model, sw_pos[i].to[j], y, x)); for (j = 0; sw_pos[i].minor[j] != -1; j++) frame_clear_bit(&minor0_p[sw_pos[i].minor[j] *FRAME_SIZE], bit_in_frame+sw_pos[i].b64[j]); @@ -2373,14 +2335,14 @@ fail: return rc; } -struct str_sw +struct str16_sw { - const char* from_str; - const char* to_str; + str16_t from; + str16_t to; }; static int get_used_switches(struct fpga_model* model, int y, int x, - struct str_sw** str_sw, int* num_sw) + struct str16_sw** str_sw, int* num_sw) { int i, num_used, rc; struct fpga_tile* tile; @@ -2403,10 +2365,10 @@ static int get_used_switches(struct fpga_model* model, int y, int x, for (i = 0; i < tile->num_switches; i++) { if (!(tile->switches[i] & SWITCH_USED)) continue; - (*str_sw)[*num_sw].from_str = - fpga_switch_str(model, y, x, i, SW_FROM); - (*str_sw)[*num_sw].to_str = - fpga_switch_str(model, y, x, i, SW_TO); + (*str_sw)[*num_sw].from = + fpga_switch_str_i(model, y, x, i, SW_FROM); + (*str_sw)[*num_sw].to = + fpga_switch_str_i(model, y, x, i, SW_TO); (*num_sw)++; } return 0; @@ -2420,16 +2382,16 @@ fail: // the indices into str_sw were the matches were made. // If not all to-from pairs were found (or none), returns 0. static int find_switches(struct iologic_sw_pos* search_sw, - struct str_sw* str_sw, int num_str_sw, int (*found)[MAX_IOLOGIC_SWBLOCK]) + struct str16_sw* str_sw, int num_str_sw, int (*found)[MAX_IOLOGIC_SWBLOCK]) { int i, j; for (i = 0; i < MAX_IOLOGIC_SWBLOCK && search_sw->to[i]; i++) { for (j = 0; j < num_str_sw; j++) { - if (!str_sw[j].to_str) + if (!str_sw[j].to) continue; - if (strcmp(str_sw[j].to_str, search_sw->to[i]) - || strcmp(str_sw[j].from_str, search_sw->from[i])) + if (str_sw[j].to != search_sw->to[i] + || str_sw[j].from != search_sw->from[i]) continue; (*found)[i] = j; break; @@ -2445,25 +2407,22 @@ static int write_iologic_sw(struct fpga_bits* bits, struct fpga_model* model, { int i, j, row_num, row_pos, start_in_frame, rc; struct iologic_sw_pos* sw_pos; - struct str_sw* str_sw; + struct str16_sw* str_sw; int found_i[MAX_IOLOGIC_SWBLOCK]; int num_sw, num_found; RC_CHECK(model); if (x < LEFT_SIDE_WIDTH) { if (x != LEFT_IO_DEVS) FAIL(EINVAL); - sw_pos = s_left_io_swpos; + sw_pos = s_leftright_swpos; } else if (x >= model->x_width-RIGHT_SIDE_WIDTH) { if (x != model->x_width - RIGHT_IO_DEVS_O) FAIL(EINVAL); - sw_pos = s_right_io_swpos; - } else if (y == TOP_OUTER_IO) - sw_pos = s_top_outer_io_swpos; - else if (y == TOP_INNER_IO) - sw_pos = s_top_inner_io_swpos; - else if (y == model->y_height-BOT_INNER_IO) - sw_pos = s_bot_inner_io_swpos; - else if (y == model->y_height-BOT_OUTER_IO) - sw_pos = s_bot_outer_io_swpos; + sw_pos = s_leftright_swpos; + } else if (y == TOP_OUTER_IO + || y == TOP_INNER_IO + || y == model->y_height-BOT_INNER_IO + || y == model->y_height-BOT_OUTER_IO) + sw_pos = s_topbot_swpos; else FAIL(EINVAL); is_in_row(model, y, &row_num, &row_pos); @@ -2487,16 +2446,17 @@ static int write_iologic_sw(struct fpga_bits* bits, struct fpga_model* model, } // remove switches from 'used' array for (j = 0; j < num_found; j++) - str_sw[found_i[j]].to_str = 0; + str_sw[found_i[j]].to = STRIDX_NO_ENTRY; } // check whether all switches were found for (i = 0; i < num_sw; i++) { - if (!str_sw[i].to_str) + if (str_sw[i].to == STRIDX_NO_ENTRY) continue; fprintf(stderr, "#E %s:%i unsupported switch " - "y%i x%i %s -> %s\n", __FILE__, __LINE__, - y, x, str_sw[i].from_str, str_sw[i].to_str); + "y%i x%i %s -> %s\n", __FILE__, __LINE__, y, x, + strarray_lookup(&model->str, str_sw[i].from), + strarray_lookup(&model->str, str_sw[i].to)); } free(str_sw); return 0; diff --git a/libs/control.c b/libs/control.c index 6be8d1c..5ced012 100644 --- a/libs/control.c +++ b/libs/control.c @@ -37,7 +37,8 @@ int fpga_find_iob(struct fpga_model *model, const char *sitename, break; } if (j >= model->die->num_t2_ios) { - HERE(); + fprintf(stderr, "#E %s:%i fpga_find_iob() cannot find %s\n", + __FILE__, __LINE__, sitename); return -1; } *y = model->die->t2_io[j].y; @@ -1459,7 +1460,7 @@ int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model, { RC_CHECK(model); #ifdef DBG_ENUM_SWITCH - printf("construct_sw_chain() %s (%s)\n", + printf("construct_sw_chain() y%i x%i %s (%s)\n", y, x, strarray_lookup(&model->str, start_switch), (from_to == SW_FROM) ? "SW_FROM" : "SW_TO"); #endif diff --git a/libs/model.h b/libs/model.h index f7353ed..c44afdd 100644 --- a/libs/model.h +++ b/libs/model.h @@ -1055,10 +1055,28 @@ enum extra_wires { MW_LAST = 3499, }; +enum iologic_wire +{ + IOLOGIC_NO_WIRE = 0, + IBUF0, IBUF1, + D_ILOGIC_SITE, D_ILOGIC_SITE_S, + D_ILOGIC_IDATAIN_IODELAY, D_ILOGIC_IDATAIN_IODELAY_S, + DFB_ILOGIC_SITE, DFB_ILOGIC_SITE_S, + FABRICOUT_ILOGIC_SITE, FABRICOUT_ILOGIC_SITE_S, + O0, O1, + OQ_OLOGIC_SITE, OQ_OLOGIC_SITE_S, + D1_OLOGIC_SITE, D1_OLOGIC_SITE_S, + IOI_LOGICOUT0, IOI_INTER_LOGICOUT0, + IOI_LOGICOUT7, IOI_INTER_LOGICOUT7, + IOI_LOGICIN_B31 +}; + const char *fpga_connpt_str(struct fpga_model *model, enum extra_wires wire, int y, int x, int dest_y, int dest_x); str16_t fpga_wire2str_yx(struct fpga_model *model, enum extra_wires wire, int y, int x); +str16_t fpga_iologic_wire2str_yx(struct fpga_model *model, + enum iologic_wire wire, int y, int 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); diff --git a/libs/model_helper.c b/libs/model_helper.c index caa8776..6c9170d 100644 --- a/libs/model_helper.c +++ b/libs/model_helper.c @@ -1611,6 +1611,109 @@ str16_t fpga_wire2str_yx(struct fpga_model *model, enum extra_wires wire, return str_i; } +str16_t fpga_iologic_wire2str_yx(struct fpga_model *model, + enum iologic_wire wire, int y, int x) +{ + switch (wire) { + case D_ILOGIC_SITE: + return strarray_find(&model->str, "D_ILOGIC_SITE"); + case D_ILOGIC_SITE_S: + return strarray_find(&model->str, "D_ILOGIC_SITE_S"); + case D_ILOGIC_IDATAIN_IODELAY: + return strarray_find(&model->str, "D_ILOGIC_IDATAIN_IODELAY"); + case D_ILOGIC_IDATAIN_IODELAY_S: + return strarray_find(&model->str, "D_ILOGIC_IDATAIN_IODELAY_S"); + case DFB_ILOGIC_SITE: + return strarray_find(&model->str, "DFB_ILOGIC_SITE"); + case DFB_ILOGIC_SITE_S: + return strarray_find(&model->str, "DFB_ILOGIC_SITE_S"); + case FABRICOUT_ILOGIC_SITE: + return strarray_find(&model->str, "FABRICOUT_ILOGIC_SITE"); + case FABRICOUT_ILOGIC_SITE_S: + return strarray_find(&model->str, "FABRICOUT_ILOGIC_SITE_S"); + case OQ_OLOGIC_SITE: + return strarray_find(&model->str, "OQ_OLOGIC_SITE"); + case OQ_OLOGIC_SITE_S: + return strarray_find(&model->str, "OQ_OLOGIC_SITE_S"); + case D1_OLOGIC_SITE: + return strarray_find(&model->str, "D1_OLOGIC_SITE"); + case D1_OLOGIC_SITE_S: + return strarray_find(&model->str, "D1_OLOGIC_SITE_S"); + case IOI_LOGICOUT0: + return strarray_find(&model->str, "IOI_LOGICOUT0"); + case IOI_INTER_LOGICOUT0: + return strarray_find(&model->str, "IOI_INTER_LOGICOUT0"); + case IOI_LOGICOUT7: + return strarray_find(&model->str, "IOI_LOGICOUT7"); + case IOI_INTER_LOGICOUT7: + return strarray_find(&model->str, "IOI_INTER_LOGICOUT7"); + case IOI_LOGICIN_B31: + return strarray_find(&model->str, "IOI_LOGICIN_B31"); + default: ; + } + if (x < LEFT_SIDE_WIDTH) { + if (x != LEFT_IO_DEVS) + { HERE(); return STRIDX_NO_ENTRY; } + if (wire == IBUF0) + return strarray_find(&model->str, "LIOI_IOB_IBUF0"); + if (wire == IBUF1) + return strarray_find(&model->str, "LIOI_IOB_IBUF1"); + if (wire == O0) + return strarray_find(&model->str, "LIOI_IOB_O0"); + if (wire == O1) + return strarray_find(&model->str, "LIOI_IOB_O1"); + } else if (x >= model->x_width-RIGHT_SIDE_WIDTH) { + if (x != model->x_width - RIGHT_IO_DEVS_O) + { HERE(); return STRIDX_NO_ENTRY; } + if (wire == IBUF0) + return strarray_find(&model->str, "RIOI_IOB_IBUF0"); + if (wire == IBUF1) + return strarray_find(&model->str, "RIOI_IOB_IBUF1"); + if (wire == O0) + return strarray_find(&model->str, "RIOI_IOB_O0"); + if (wire == O1) + return strarray_find(&model->str, "RIOI_IOB_O1"); + } else if (y == TOP_OUTER_IO) { + if (wire == IBUF0) + return strarray_find(&model->str, "TIOI_OUTER_IBUF0"); + if (wire == IBUF1) + return strarray_find(&model->str, "TIOI_OUTER_IBUF1"); + if (wire == O0) + return strarray_find(&model->str, "TIOI_OUTER_O0"); + if (wire == O1) + return strarray_find(&model->str, "TIOI_OUTER_O1"); + } else if (y == TOP_INNER_IO) { + if (wire == IBUF0) + return strarray_find(&model->str, "TIOI_INNER_IBUF0"); + if (wire == IBUF1) + return strarray_find(&model->str, "TIOI_INNER_IBUF1"); + if (wire == O0) + return strarray_find(&model->str, "TIOI_INNER_O0"); + if (wire == O1) + return strarray_find(&model->str, "TIOI_INNER_O1"); + } else if (y == model->y_height-BOT_INNER_IO) { + if (wire == IBUF0) + return strarray_find(&model->str, "BIOI_INNER_IBUF0"); + if (wire == IBUF1) + return strarray_find(&model->str, "BIOI_INNER_IBUF1"); + if (wire == O0) + return strarray_find(&model->str, "BIOI_INNER_O0"); + if (wire == O1) + return strarray_find(&model->str, "BIOI_INNER_O1"); + } else if (y == model->y_height-BOT_OUTER_IO) { + if (wire == IBUF0) + return strarray_find(&model->str, "BIOI_OUTER_IBUF0"); + if (wire == IBUF1) + return strarray_find(&model->str, "BIOI_OUTER_IBUF1"); + if (wire == O0) + return strarray_find(&model->str, "BIOI_OUTER_O0"); + if (wire == O1) + return strarray_find(&model->str, "BIOI_OUTER_O1"); + } + HERE(); + return STRIDX_NO_ENTRY; +} + const char *fpga_wire2str(enum extra_wires wire) { enum { NUM_BUFS = 8, BUF_SIZE = MAX_WIRENAME_LEN }; diff --git a/libs/parts.c b/libs/parts.c index 6c86978..a7f39e4 100644 --- a/libs/parts.c +++ b/libs/parts.c @@ -265,7 +265,7 @@ const struct xc_die *xc_die_info(int idcode) /* 20 */ 87, 86, 85, 84, /* 24 */ 77, 76, 75, 74, /* 28 */ 29, 28, 27, 26 }, - // todo: gclk 2/3/28 and 29 positions not yet verified + // todo: gclk 2,3,28,29 positions not yet verified .gclk_t2_switches = { // 16-bit words into type2 data /* 0 */ 20*4+ 6, 20*4+ 9, 20*4+ 0, 20*4+ 3, /* 4 */ 190*4+18, 190*4+21, 190*4+12, 190*4+15,