improved iologic switches

This commit is contained in:
Wolfgang Spraul 2013-01-24 00:38:54 -05:00
parent 90f5cfe84f
commit 7c12ea66a7
6 changed files with 367 additions and 239 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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 };

View File

@ -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,