From c17d5023592a89ecf6bb4dccf5b1ad60bdec64d9 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Thu, 30 Aug 2012 14:40:54 +0200 Subject: [PATCH] minor testing additions - next: big autotest cleanup --- autotest.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++-- bit_regs.c | 26 ++++++- control.c | 2 + control.h | 11 +-- 4 files changed, 227 insertions(+), 13 deletions(-) diff --git a/autotest.c b/autotest.c index f57afd8..c54879f 100644 --- a/autotest.c +++ b/autotest.c @@ -280,7 +280,7 @@ static int test_device_fingers(struct test_state* tstate, int y, int x, // fprintf_net(stdout, tstate->model, net_idx); // printf("set %s\n", fmt_swset(tstate->model, switch_to.dest_y, switch_to.dest_x, &chain.set, from_to)); -#if 0 +#if 1 rc = diff_printf(tstate); if (rc) FAIL(rc); #endif @@ -295,6 +295,189 @@ fail: return rc; } +static int test_logic_net(struct test_state* tstate, int logic_y, int logic_x, + int type_idx, pinw_idx_t port, const struct sw_set* logic_switch_set, + int routing_y, int routing_x, swidx_t routing_sw1, swidx_t routing_sw2) +{ + net_idx_t net_idx; + struct sw_set routing_switches; + int rc; + + rc = fpga_net_new(tstate->model, &net_idx); + if (rc) FAIL(rc); + + // add port + rc = fpga_net_add_port(tstate->model, net_idx, logic_y, logic_x, + fpga_dev_idx(tstate->model, logic_y, logic_x, DEV_LOGIC, + type_idx), port); + 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); + if (rc) FAIL(rc); + + // add switches in routing tile + routing_switches.len = 0; + if (routing_sw1 == NO_SWITCH) FAIL(EINVAL); + 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); + if (rc) FAIL(rc); + +#if 0 + printf("lnet %s %s\n", fpga_switch_print(tstate->model, routing_y, + routing_x, routing_sw1), routing_sw2 == NO_SWITCH ? "" + : fpga_switch_print(tstate->model, routing_y, routing_x, routing_sw2)); +#endif +#if 1 + rc = diff_printf(tstate); + if (rc) FAIL(rc); +#endif + fpga_net_delete(tstate->model, net_idx); + return 0; +fail: + return rc; +} + +static int test_logic_fingers(struct test_state* tstate, int y, int x, + int type, int type_idx, str16_t* done_pinw_list, int* done_pinw_len, + swidx_t* l2_done_list, int* l2_done_len) +{ + struct fpga_device* dev; + struct switch_to_yx switch_to; + struct sw_chain chain; + net_idx_t net_idx; + int i, j, k, l, from_to, direction, rc; + struct sw_set set_l1, set_l2; + struct fpga_tile* switch_tile; + + rc = fdev_set_required_pins(tstate->model, y, x, type, type_idx); + if (rc) FAIL(rc); +// fdev_print_required_pins(tstate->model, y, x, type, type_idx); + + dev = fdev_p(tstate->model, y, x, type, type_idx); + if (!dev) FAIL(EINVAL); + for (i = 0; i < dev->pinw_req_total; i++) { + + // do every pinw only once across all configs + for (j = 0; j < *done_pinw_len; j++) { + if (done_pinw_list[j] == dev->pinw[dev->pinw_req_for_cfg[i]]) + break; + } + if (j < *done_pinw_len) + continue; + done_pinw_list[(*done_pinw_len)++] = dev->pinw[dev->pinw_req_for_cfg[i]]; + + from_to = (i < dev->pinw_req_in) ? SW_TO : SW_FROM; + switch_to.yx_req = YX_ROUTING_TILE; + switch_to.flags = SWTO_YX_DEF; + switch_to.model = tstate->model; + switch_to.y = y; + switch_to.x = x; + switch_to.start_switch = dev->pinw[dev->pinw_req_for_cfg[i]]; + switch_to.from_to = from_to; + rc = fpga_switch_to_yx(&switch_to); + if (rc) FAIL(rc); +// printf_switch_to_result(&switch_to); + + switch_tile = YX_TILE(tstate->model, switch_to.dest_y, switch_to.dest_x); + rc = fpga_swset_fromto(tstate->model, switch_to.dest_y, + switch_to.dest_x, switch_to.dest_connpt, from_to, &set_l1); + if (rc) FAIL(rc); + +// if (1||(i < dev->pinw_req_in)) { +// if (i >= dev->pinw_req_in) { + if (1) { +// fpga_swset_print(tstate->model, switch_to.dest_y, switch_to.dest_x, &set_l1, from_to); + for (j = 0; j < set_l1.len; j++) { + rc = test_logic_net(tstate, y, x, type_idx, dev->pinw_req_for_cfg[i], + &switch_to.set, switch_to.dest_y, switch_to.dest_x, + set_l1.sw[j], NO_SWITCH); + if (rc) FAIL(rc); + // level one switches themselves cannot become duplicates + // because we check for unique pinwires already. but we still + // need to add them to the done_list to compare against + // future l2 switches. +// todo: rename l2_done_list to just done_list + l2_done_list[(*l2_done_len)++] = set_l1.sw[j]; + + rc = fpga_swset_fromto(tstate->model, switch_to.dest_y, + switch_to.dest_x, CONNPT_STR16(switch_tile, + SW_I(switch_tile->switches[set_l1.sw[j]], !from_to)), + i < dev->pinw_req_in ? from_to : !from_to, &set_l2); + if (rc) FAIL(rc); + + for (k = 0; k < set_l2.len; k++) { + // on an out pin, we are reversing direction and looking + // for other switches pointing *to* the output, but we + // can skip ourselves... + if (set_l2.sw[k] == set_l1.sw[j]) + continue; + + // The level 1 switches cannot duplicate because we + // already track unique pinwires. But level 2 switches + // must be checked for duplicates. + for (l = 0; l < *l2_done_len; l++) { + if (l2_done_list[l] == set_l2.sw[k]) + break; + } + if (l < *l2_done_len) + continue; + l2_done_list[(*l2_done_len)++] = set_l2.sw[k]; + + rc = test_logic_net(tstate, y, x, type_idx, dev->pinw_req_for_cfg[i], + &switch_to.set, switch_to.dest_y, switch_to.dest_x, + set_l1.sw[j], set_l2.sw[k]); + if (rc) FAIL(rc); + } + } + } + + +#if 0 + + + // loop twice, first continue in the same direction as + // the in/out pin, second loop in reverse direction + for (direction = 0; direction <= 1; direction++) { +//printf("direction %i\n", direction); + for (j = 0; j < set_l1.len; j++) { + +//printf("j %i\n", j); + rc = fpga_swset_fromto(tstate->model, switch_to.dest_y, + switch_to.dest_x, CONNPT_STR16(switch_tile, + SW_I(switch_tile->switches[set_l1.sw[j]], !from_to)), + direction ? !from_to : from_to, &set_l2); + if (rc) FAIL(rc); + +#if 0 + rc = test_logic_net(tstate, y, x, type_idx, dev->pinw_req_for_cfg[i], + &switch_to.set, switch_to.dest_y, switch_to.dest_x, + set_l1.sw[j], NO_SWITCH); + if (rc) FAIL(rc); +#endif + + for (k = 0; k < set_l2.len; k++) { +#if 0 + rc = test_logic_net(tstate, y, x, type_idx, dev->pinw_req_for_cfg[i], + &switch_to.set, switch_to.dest_y, switch_to.dest_x, + set_l1.sw[j], set_l2.sw[k]); + if (rc) FAIL(rc); +#endif + } +// fpga_swset_print(tstate->model, switch_to.dest_y, switch_to.dest_x, &set_l2, direction ? !from_to: from_to); + } + } +#endif + } + return 0; +fail: + return rc; +} + // goal: use all switches in a routing switchbox int test_logic_routing_switches(struct test_state* tstate); int test_logic_routing_switches(struct test_state* tstate) @@ -302,13 +485,16 @@ int test_logic_routing_switches(struct test_state* tstate) int a_to_d[] = { A6_LUT, B6_LUT, C6_LUT, D6_LUT }; int idx_enum[] = { DEV_LOGM, DEV_LOGX }; int y, x, i, j, k, rc; - swidx_t done_list[MAX_SWITCHBOX_SIZE]; - int done_list_len; - + swidx_t l2_done_list[MAX_SWITCHBOX_SIZE]; + int l2_done_len; + str16_t done_pinw_list[2000]; + int done_pinw_len; + y = 68; x = 13; - done_list_len = 0; + done_pinw_len = 0; + l2_done_len = 0; for (i = 0; i < sizeof(idx_enum)/sizeof(*idx_enum); i++) { for (j = 0; j < sizeof(a_to_d)/sizeof(*a_to_d); j++) { for (k = '1'; k <= '6'; k++) { @@ -316,8 +502,9 @@ int test_logic_routing_switches(struct test_state* tstate) idx_enum[i], a_to_d[j], pf("A%c", k), ZTERM); if (rc) FAIL(rc); - rc = test_device_fingers(tstate, y, x, DEV_LOGIC, - idx_enum[i], done_list, &done_list_len); + rc = test_logic_fingers(tstate, y, x, DEV_LOGIC, + idx_enum[i], done_pinw_list, &done_pinw_len, + l2_done_list, &l2_done_len); if (rc) FAIL(rc); fdev_delete(tstate->model, y, x, DEV_LOGIC, idx_enum[i]); } diff --git a/bit_regs.c b/bit_regs.c index 2d47832..f1af665 100644 --- a/bit_regs.c +++ b/bit_regs.c @@ -740,6 +740,25 @@ static void printf_routing_2minors(uint8_t* bits, int row, int major, } } +static void printf_v64_mi20(uint8_t* bits, int row, int major) +{ + int y, i, hclk; + uint64_t u64; + char bit_str[65]; + + bit_str[64] = 0; + for (y = 0; y < 16; y++) { + hclk = (y < 8) ? 0 : 2; + u64 = frame_get_u64(bits + y*8 + hclk); + if (u64) { + for (i = 0; i < 64; i++) + bit_str[i] = (u64 & (1ULL << i)) ? '1' : '0'; + printf("r%i ma%i v64_%02i mi20 %s\n", + row, major, y, bit_str); + } + } +} + static int dump_bits(struct fpga_config* cfg) { int row, major, minor, i, j, off, offset_in_frame; @@ -795,7 +814,12 @@ static int dump_bits(struct fpga_config* cfg) // 0:20 routing minor pairs for (i = 0; i < 10; i++) - printf_routing_2minors(&cfg->bits.d[off+i*2*FRAME_SIZE], row, major, i*2); + printf_routing_2minors(&cfg->bits.d[ + off+i*2*FRAME_SIZE], row, major, i*2); + + // mi20 as 64-char 0/1 string + printf_v64_mi20(&cfg->bits.d[ + off+20*FRAME_SIZE], row, major); } else if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major) == MAJ_BRAM) { ramb16_cfg_t ramb16_cfg[4]; diff --git a/control.c b/control.c index ac42005..15b799f 100644 --- a/control.c +++ b/control.c @@ -603,6 +603,8 @@ int fpga_swset_fromto(struct fpga_model* model, int y, int x, set->len = 0; idx = fpga_switch_first(model, y, x, start_switch, from_to); while (idx != NO_SWITCH) { + if (set->len >= SW_SET_SIZE) + { HERE(); return 0; } set->sw[set->len++] = idx; idx = fpga_switch_next(model, y, x, idx, from_to); } diff --git a/control.h b/control.h index 02c9958..c113f76 100644 --- a/control.h +++ b/control.h @@ -63,11 +63,12 @@ void fpga_conn_dest(struct fpga_model* model, int y, int x, // typedef int swidx_t; // swidx_t is an index into the uint32_t switches array -// SW_SET_SIZE should be enough for both the largest number -// of switches that can go from or to one specific connection -// point (32), as well as the largest depth of a path inside -// a switchbox (ca. 20). -#define SW_SET_SIZE 64 +// SW_SET_SIZE should be enough for: +// *) largest number of switches that can go from or to one +// specific connection point (ca. 32) +// *) largest depth inside a switchbox (ca. 20) +// *) some wires that go 'everywhere' like GFAN (70) +#define SW_SET_SIZE 128 struct sw_set {