a little iologic switch work

This commit is contained in:
Wolfgang Spraul 2012-09-10 08:21:26 +02:00
parent c76ae0e322
commit 1f91ec536e
5 changed files with 187 additions and 91 deletions

View File

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

View File

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

View File

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

View File

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

View File

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