a little iologic switch work
This commit is contained in:
parent
c76ae0e322
commit
1f91ec536e
189
autotest.c
189
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");
|
||||
|
|
|
@ -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;
|
||||
|
|
74
control.c
74
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;
|
||||
|
|
10
control.h
10
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user