From 1f91ec536ec4fd08432a6ca5a68e5bd604dd36ba Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Mon, 10 Sep 2012 08:21:26 +0200 Subject: [PATCH] a little iologic switch work --- autotest.c | 189 +++++++++++++++++++++++++++++++++------------------ bit_frames.c | 3 +- control.c | 74 +++++++++++++++----- control.h | 10 +-- floorplan.c | 2 +- 5 files changed, 187 insertions(+), 91 deletions(-) diff --git a/autotest.c b/autotest.c index 12b1b02..4ffd719 100644 --- a/autotest.c +++ b/autotest.c @@ -206,8 +206,8 @@ static int test_logic_net(struct test_state* tstate, int logic_y, int logic_x, if (rc) FAIL(rc); // add (one) switch in logic tile - rc = fpga_net_add_switches(tstate->model, net_idx, - logic_y, logic_x, logic_switch_set); + rc = fpga_net_add_sw(tstate->model, net_idx, + logic_y, logic_x, logic_switch_set->sw, logic_switch_set->len); if (rc) FAIL(rc); // add switches in routing tile @@ -216,8 +216,8 @@ static int test_logic_net(struct test_state* tstate, int logic_y, int logic_x, routing_switches.sw[routing_switches.len++] = routing_sw1; if (routing_sw2 != NO_SWITCH) routing_switches.sw[routing_switches.len++] = routing_sw2; - rc = fpga_net_add_switches(tstate->model, net_idx, - routing_y, routing_x, &routing_switches); + rc = fpga_net_add_sw(tstate->model, net_idx, + routing_y, routing_x, routing_switches.sw, routing_switches.len); if (rc) FAIL(rc); if (dbg) @@ -499,6 +499,120 @@ fail: return rc; } +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; + net_idx_t net_idx; + int i, from_to, rc; + + rc = fdev_set_required_pins(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx); + if (rc) FAIL(rc); + if (tstate->dry_run) + fdev_print_required_pins(tstate->model, iob_y, iob_x, DEV_IOB, iob_type_idx); + 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; + + // 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; + rc = fpga_switch_to_yx(&switch_to); + if (rc) FAIL(rc); + if (tstate->dry_run) + printf_switch_to_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, /*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 = fpga_net_new(tstate->model, &net_idx); + if (rc) FAIL(rc); + + // add iob port + rc = fpga_net_add_port(tstate->model, net_idx, iob_y, iob_x, + fpga_dev_idx(tstate->model, iob_y, iob_x, DEV_IOB, + iob_type_idx), IOB_IN_O); + if (rc) FAIL(rc); + + // add switch in iob tile + rc = fpga_net_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 = fpga_net_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); + } + rc = diff_printf(tstate); + if (rc) FAIL(rc); + + // add last switch + rc = fpga_net_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); + + rc = diff_printf(tstate); + if (rc) FAIL(rc); + + fpga_net_delete(tstate->model, net_idx); + } + destruct_sw_chain(&chain); + } + return 0; +fail: + return rc; +} + +static int test_iologic_switches(struct test_state* tstate) +{ + char iob_name[32]; + int iob_y, iob_x, iob_type_idx, i, rc; + + for (i = 45; i <= 48; i++) { + snprintf(iob_name, sizeof(iob_name), "P%i", i); + + // 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); + 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); + + // 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); + 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); + } + return 0; +fail: + return rc; +} + #define DEFAULT_DIFF_EXEC "./autotest_diff.sh" static void printf_help(const char* argv_0, const char** available_tests) @@ -529,7 +643,7 @@ int main(int argc, char** argv) char param[1024], cmdline_test[1024]; int i, param_skip, rc; const char* available_tests[] = - { "logic_cfg", "logic_sw", 0 }; + { "logic_cfg", "logic_sw", "io_sw", 0 }; // flush after every line is better for the autotest // output, tee, etc. @@ -645,29 +759,10 @@ int main(int argc, char** argv) rc = test_logic_switches(&tstate); if (rc) FAIL(rc); } - - // iob_sw: test_iob_switches - // test_iologic_switches - -#if 0 -// test_swchain: -// printf_swchain(&model, 69, 13, strarray_find(&model.str, "BIOI_INNER_IBUF0"), SW_FROM, SW_SET_SIZE); - { - swidx_t done_list[MAX_SWITCHBOX_SIZE]; - int done_list_len = 0; - printf_swchain(&model, 68, 12, strarray_find(&model.str, "LOGICIN_B29"), - SW_TO, SW_SET_SIZE, done_list, &done_list_len); -#if 0 - printf_swchain(&model, 68, 12, strarray_find(&model.str, "NR1E0"), - SW_FROM, SW_SET_SIZE, done_list, &done_list_len); - printf_swchain(&model, 68, 12, strarray_find(&model.str, "NN2E0"), - SW_FROM, SW_SET_SIZE, done_list, &done_list_len); - printf_swchain(&model, 68, 12, strarray_find(&model.str, "SE2E2"), - SW_FROM, SW_SET_SIZE, done_list, &done_list_len); -#endif + if (!strcmp(cmdline_test, "io_sw")) { + rc = test_iologic_switches(&tstate); + if (rc) FAIL(rc); } -#endif - #if 0 struct fpga_model model; struct fpga_device* P46_dev, *P48_dev, *logic_dev; @@ -677,43 +772,6 @@ int main(int argc, char** argv) struct switch_to_yx switch_to; net_idx_t P46_net; - // configure P46 - rc = fpga_find_iob(&model, "P46", &P46_y, &P46_x, &P46_type_idx); - if (rc) FAIL(rc); - P46_dev_idx = fpga_dev_idx(&model, P46_y, P46_x, DEV_IOB, P46_type_idx); - if (P46_dev_idx == NO_DEV) FAIL(EINVAL); - P46_dev = FPGA_DEV(&model, P46_y, P46_x, P46_dev_idx); - P46_dev->instantiated = 1; - strcpy(P46_dev->iob.istandard, IO_LVCMOS33); - P46_dev->iob.bypass_mux = BYPASS_MUX_I; - P46_dev->iob.I_mux = IMUX_I; - - // configure P48 - rc = fpga_find_iob(&model, "P48", &P48_y, &P48_x, &P48_type_idx); - if (rc) FAIL(rc); - P48_dev_idx = fpga_dev_idx(&model, P48_y, P48_x, DEV_IOB, P48_type_idx); - if (P48_dev_idx == NO_DEV) FAIL(EINVAL); - P48_dev = FPGA_DEV(&model, P48_y, P48_x, P48_dev_idx); - P48_dev->instantiated = 1; - strcpy(P48_dev->iob.ostandard, IO_LVCMOS33); - P48_dev->iob.drive_strength = 12; - P48_dev->iob.O_used = 1; - P48_dev->iob.slew = SLEW_SLOW; - P48_dev->iob.suspend = SUSP_3STATE; - - // configure logic - logic_dev_idx = fpga_dev_idx(&model, /*y*/ 68, /*x*/ 13, - DEV_LOGIC, DEV_LOGX); - if (logic_dev_idx == NO_DEV) FAIL(EINVAL); - logic_dev = FPGA_DEV(&model, /*y*/ 68, /*x*/ 13, logic_dev_idx); - logic_dev->instantiated = 1; - logic_dev->logic.D_used = 1; - rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM); - if (rc) FAIL(rc); - - rc = diff_printf(&tstate); - if (rc) FAIL(rc); - // configure net from P46.I to logic.D3 rc = fpga_net_new(&model, &P46_net); if (rc) FAIL(rc); @@ -806,9 +864,6 @@ int main(int argc, char** argv) rc = fpga_net_add_switches(&model, P46_net, c.y, c.x, &c.set); if (rc) FAIL(rc); } - - rc = test_net2(&tstate, P46_net); - if (rc) FAIL(rc); #endif printf("\n"); diff --git a/bit_frames.c b/bit_frames.c index 907ac24..d22dd46 100644 --- a/bit_frames.c +++ b/bit_frames.c @@ -641,7 +641,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) for (i = 0; i < es.num_sw_yx; i++) { rc = fpga_net_new(model, &net_idx); if (rc) FAIL(rc); - rc = fpga_net_add_switch(model, net_idx, es.sw_yx[i].y, es.sw_yx[i].x, es.sw_yx[i].idx); + rc = fpga_net_add_sw(model, net_idx, es.sw_yx[i].y, + es.sw_yx[i].x, &es.sw_yx[i].idx, 1); if (rc) FAIL(rc); } return 0; diff --git a/control.c b/control.c index 8cdeb37..5b56f4e 100644 --- a/control.c +++ b/control.c @@ -539,6 +539,46 @@ fail: return rc; } +int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx) +{ + struct fpga_device* dev; + int rc; + + dev = fdev_p(model, y, x, DEV_IOB, type_idx); + if (!dev) FAIL(EINVAL); + rc = reset_required_pins(dev); + if (rc) FAIL(rc); + + strcpy(dev->u.iob.istandard, IO_LVCMOS33); + dev->u.iob.bypass_mux = BYPASS_MUX_I; + dev->u.iob.I_mux = IMUX_I; + dev->instantiated = 1; + return 0; +fail: + return rc; +} + +int fdev_iob_output(struct fpga_model* model, int y, int x, int type_idx) +{ + struct fpga_device* dev; + int rc; + + dev = fdev_p(model, y, x, DEV_IOB, type_idx); + if (!dev) FAIL(EINVAL); + rc = reset_required_pins(dev); + if (rc) FAIL(rc); + + strcpy(dev->u.iob.ostandard, IO_LVCMOS33); + dev->u.iob.drive_strength = 12; + dev->u.iob.O_used = 1; + dev->u.iob.slew = SLEW_SLOW; + dev->u.iob.suspend = SUSP_3STATE; + dev->instantiated = 1; + return 0; +fail: + return rc; +} + static void scan_lut_digits(const char* s, int* digits) { int i; @@ -598,6 +638,13 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type, } } } + return 0; + } + if (type == DEV_IOB) { + if (dev->u.iob.I_mux) + add_req_outpin(dev, IOB_OUT_I); + if (dev->u.iob.O_used) + add_req_inpin(dev, IOB_IN_O); } return 0; fail: @@ -1062,7 +1109,7 @@ int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model, chain->y = y; chain->x = x; chain->from_to = from_to; - chain->max_depth = max_depth; + chain->max_depth = (max_depth < 0) ? SW_SET_SIZE : max_depth; if (block_list) { chain->block_list = block_list; chain->block_list_len = block_list_len; @@ -1525,17 +1572,8 @@ fail: return rc; } -int fpga_net_add_switch(struct fpga_model* model, net_idx_t net_i, - int y, int x, swidx_t one_sw) -{ - struct sw_set set; - set.sw[0] = one_sw; - set.len = 1; - return fpga_net_add_switches(model, net_i, y, x, &set); -} - -int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, - int y, int x, const struct sw_set* set) +int fpga_net_add_sw(struct fpga_model* model, net_idx_t net_i, + int y, int x, const swidx_t* switches, int num_sw) { struct fpga_net* net; int i, rc; @@ -1544,16 +1582,16 @@ int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, if (rc) FAIL(rc); net = &model->nets[net_i-1]; - if (net->len+set->len > MAX_NET_LEN) + if (net->len+num_sw > MAX_NET_LEN) FAIL(EINVAL); - for (i = 0; i < set->len; i++) { + for (i = 0; i < num_sw; i++) { net->el[net->len].y = y; net->el[net->len].x = x; - if (OUT_OF_U16(set->sw[i])) FAIL(EINVAL); - if (fpga_switch_is_used(model, y, x, set->sw[i])) + if (OUT_OF_U16(switches[i])) FAIL(EINVAL); + if (fpga_switch_is_used(model, y, x, switches[i])) HERE(); - fpga_switch_enable(model, y, x, set->sw[i]); - net->el[net->len].idx = set->sw[i]; + fpga_switch_enable(model, y, x, switches[i]); + net->el[net->len].idx = switches[i]; net->len++; } return 0; diff --git a/control.h b/control.h index 52567c3..30d7e7a 100644 --- a/control.h +++ b/control.h @@ -60,6 +60,9 @@ int fdev_logic_sync(struct fpga_model* model, int y, int x, int type_idx, int fdev_logic_ceused(struct fpga_model* model, int y, int x, int type_idx); int fdev_logic_srused(struct fpga_model* model, int y, int x, int type_idx); +int fdev_iob_input(struct fpga_model* model, int y, int x, int type_idx); +int fdev_iob_output(struct fpga_model* model, int y, int x, int type_idx); + int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type, int type_idx); void fdev_print_required_pins(struct fpga_model* model, int y, int x, @@ -211,6 +214,7 @@ void destruct_sw_conns(struct sw_conns* conns); // NO_CONN (-1) if there is no other connection. int fpga_switch_conns(struct sw_conns* conns); +// max_depth can be -1 for internal maximum (SW_SET_SIZE) void printf_swchain(struct fpga_model* model, int y, int x, str16_t sw, int from_to, int max_depth, swidx_t* block_list, int* block_list_len); @@ -286,10 +290,8 @@ int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next); struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i); int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i, int y, int x, dev_idx_t dev_idx, pinw_idx_t pinw_idx); -int fpga_net_add_switch(struct fpga_model* model, net_idx_t net_i, - int y, int x, swidx_t one_sw); -int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, - int y, int x, const struct sw_set* set); +int fpga_net_add_sw(struct fpga_model* model, net_idx_t net_i, + int y, int x, const swidx_t* switches, int num_sw); void fpga_net_free_all(struct fpga_model* model); void fprintf_net(FILE* f, struct fpga_model* model, net_idx_t net_i); diff --git a/floorplan.c b/floorplan.c index 06f6f7f..ef6fbe3 100644 --- a/floorplan.c +++ b/floorplan.c @@ -847,7 +847,7 @@ static void read_net_line(struct fpga_model* model, const char* line, int start) if (fpga_switch_is_used(model, y_coord, x_coord, sw.sw[0])) HERE(); sw.len = 1; - if (fpga_net_add_switches(model, net_idx, y_coord, x_coord, &sw)) + if (fpga_net_add_sw(model, net_idx, y_coord, x_coord, sw.sw, sw.len)) HERE(); return; }