improved iologic switches
This commit is contained in:
parent
90f5cfe84f
commit
7c12ea66a7
208
autotest.c
208
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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
18
libs/model.h
18
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);
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue
Block a user