what a mess, this can only be the first step...
This commit is contained in:
parent
c852442ad3
commit
05fe89cb9d
124
autotest.c
124
autotest.c
|
@ -110,7 +110,8 @@ static void cut_sw_from_end(struct fpga_net* net, int cut_o)
|
|||
net->len = 2 + net->len-cut_o;
|
||||
}
|
||||
|
||||
static int test_net(struct test_state* tstate, net_idx_t net_i)
|
||||
int test_net(struct test_state* tstate, net_idx_t net_i);
|
||||
int test_net(struct test_state* tstate, net_idx_t net_i)
|
||||
{
|
||||
struct fpga_net* net;
|
||||
struct fpga_net copy_net;
|
||||
|
@ -136,7 +137,8 @@ static int test_net(struct test_state* tstate, net_idx_t net_i)
|
|||
net->el[2].y, net->el[2].x,
|
||||
fpga_switch_str_i(tstate->model,
|
||||
net->el[2].y, net->el[2].x,
|
||||
net->el[2].idx, SW_TO), SW_TO, 1);
|
||||
net->el[2].idx, SW_TO),
|
||||
SW_TO, 1, 0, 0);
|
||||
same_len = sizeof(same_sw)/sizeof(*same_sw);
|
||||
rc = fpga_switch_same_fromto(tstate->model,
|
||||
net->el[2].y, net->el[2].x,
|
||||
|
@ -154,7 +156,8 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int test_net2(struct test_state* tstate, net_idx_t net_i)
|
||||
int test_net2(struct test_state* tstate, net_idx_t net_i);
|
||||
int test_net2(struct test_state* tstate, net_idx_t net_i)
|
||||
{
|
||||
struct fpga_net* net;
|
||||
struct fpga_net copy_net;
|
||||
|
@ -174,7 +177,8 @@ static int test_net2(struct test_state* tstate, net_idx_t net_i)
|
|||
net->el[i-1].y, net->el[i-1].x,
|
||||
fpga_switch_str_i(tstate->model,
|
||||
net->el[i-1].y, net->el[i-1].x,
|
||||
net->el[i-1].idx, SW_FROM), SW_FROM, 1);
|
||||
net->el[i-1].idx, SW_FROM),
|
||||
SW_FROM, 1, 0, 0);
|
||||
same_len = sizeof(same_sw)/sizeof(*same_sw);
|
||||
rc = fpga_switch_same_fromto(tstate->model,
|
||||
net->el[i-1].y, net->el[i-1].x,
|
||||
|
@ -193,8 +197,38 @@ fail:
|
|||
return rc;
|
||||
}
|
||||
|
||||
// goal: configure logic devices in all supported variations
|
||||
int test_logic_config(struct test_state* tstate);
|
||||
int test_logic_config(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;
|
||||
|
||||
y = 68;
|
||||
x = 13;
|
||||
|
||||
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++) {
|
||||
rc = fdev_logic_set_lut(tstate->model, y, x,
|
||||
idx_enum[i], a_to_d[j], pf("A%c", k), ZTERM);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
fdev_delete(tstate->model, y, x, DEV_LOGIC, idx_enum[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_device_fingers(struct test_state* tstate, int y, int x,
|
||||
int type, int type_idx, int test_inpins, int test_outpins)
|
||||
int type, int type_idx, swidx_t* block_list, int* block_list_len)
|
||||
{
|
||||
struct fpga_device* dev;
|
||||
struct switch_to_yx switch_to;
|
||||
|
@ -209,11 +243,6 @@ static int test_device_fingers(struct test_state* tstate, int y, int x,
|
|||
dev = fdev_p(tstate->model, y, x, type, type_idx);
|
||||
if (!dev) FAIL(EINVAL);
|
||||
for (i = 0; i < dev->pinw_req_total; i++) {
|
||||
|
||||
if ((i < dev->pinw_req_in && !test_inpins)
|
||||
|| (i >= dev->pinw_req_in && !test_outpins))
|
||||
continue;
|
||||
|
||||
from_to = (i < dev->pinw_req_in) ? SW_TO : SW_FROM;
|
||||
switch_to.yx_req = YX_ROUTING_TILE;
|
||||
switch_to.flags = SWTO_YX_DEF;
|
||||
|
@ -226,12 +255,10 @@ static int test_device_fingers(struct test_state* tstate, int y, int x,
|
|||
if (rc) FAIL(rc);
|
||||
// printf_switch_to_result(&switch_to);
|
||||
|
||||
chain.model = tstate->model;
|
||||
chain.y = switch_to.dest_y;
|
||||
chain.x = switch_to.dest_x;
|
||||
chain.start_switch = switch_to.dest_connpt;
|
||||
chain.from_to = from_to;
|
||||
chain.max_chain_size = 1;
|
||||
rc = 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, *block_list_len);
|
||||
if (rc) FAIL(rc);
|
||||
while (fpga_switch_chain(&chain) != NO_SWITCH) {
|
||||
rc = fpga_net_new(tstate->model, &net_idx);
|
||||
if (rc) FAIL(rc);
|
||||
|
@ -251,28 +278,37 @@ static int test_device_fingers(struct test_state* tstate, int y, int x,
|
|||
if (rc) FAIL(rc);
|
||||
|
||||
// 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
|
||||
rc = diff_printf(tstate);
|
||||
if (rc) FAIL(rc);
|
||||
#endif
|
||||
fpga_net_delete(tstate->model, net_idx);
|
||||
}
|
||||
*block_list_len = chain.block_list_len;
|
||||
// printf("block_list_len now %i\n", *block_list_len);
|
||||
destruct_sw_chain(&chain);
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int test_all_logic_configs(struct test_state* tstate)
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
|
||||
// todo: goal: configure valid logic with as many possible in and out
|
||||
// pins, for M and X device
|
||||
y = 68;
|
||||
x = 13;
|
||||
|
||||
done_list_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++) {
|
||||
|
@ -281,12 +317,17 @@ static int test_all_logic_configs(struct test_state* tstate)
|
|||
if (rc) FAIL(rc);
|
||||
|
||||
rc = test_device_fingers(tstate, y, x, DEV_LOGIC,
|
||||
idx_enum[i], /*in*/ 1, /*out*/ k=='1');
|
||||
idx_enum[i], done_list, &done_list_len);
|
||||
if (rc) FAIL(rc);
|
||||
fdev_delete(tstate->model, y, x, DEV_LOGIC, idx_enum[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
for (i = 0; i < done_list_len; i++) {
|
||||
printf("done %i %s\n", i, fpga_switch_print(tstate->model, 68, 12, done_list[i]));
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
|
@ -330,18 +371,37 @@ int main(int argc, char** argv)
|
|||
rc = diff_start(&tstate, "and");
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// test_logic_config
|
||||
// test_logic_routing_switches
|
||||
#if 0
|
||||
rc = test_logic_config(&tstate);
|
||||
if (rc) FAIL(rc);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
rc = test_logic_routing_switches(&tstate);
|
||||
if (rc) FAIL(rc);
|
||||
#endif
|
||||
|
||||
// test_iob_config
|
||||
// test_iologic_routing_switches
|
||||
|
||||
#if 0
|
||||
rc = test_all_logic_configs(&tstate);
|
||||
if (rc) FAIL(rc);
|
||||
// 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
|
||||
}
|
||||
#endif
|
||||
|
||||
printf_swchain(&model, 69, 13, strarray_find(&model.str, "BIOI_INNER_IBUF0"), SW_FROM, MAX_SW_DEPTH);
|
||||
// printf_swchain(&model, 68, 12, strarray_find(&model.str, "NR1E0"), SW_FROM, MAX_SW_DEPTH);
|
||||
|
||||
#if 0
|
||||
// configure P46
|
||||
|
@ -439,11 +499,14 @@ int main(int argc, char** argv)
|
|||
switch_to.from_to = SW_FROM;
|
||||
switch_to.max_switch_depth = 1;
|
||||
{
|
||||
note: update to constructor
|
||||
struct sw_chain c = {
|
||||
.model = &model, .y = switch_to.dest_y,
|
||||
.x = switch_to.dest_x+1,
|
||||
.start_switch = logic_dev->pinw[LOGIC_IN_D3],
|
||||
.from_to = SW_TO, .max_chain_size = MAX_SW_DEPTH };
|
||||
.from_to = SW_TO,
|
||||
.max_depth = SW_SET_SIZE,
|
||||
.block_list = 0 };
|
||||
if (fpga_switch_chain(&c) == NO_CONN) FAIL(EINVAL);
|
||||
if (c.set.len == 0) { HERE(); FAIL(EINVAL); }
|
||||
switch_to.target_connpt = fpga_switch_str_i(&model,
|
||||
|
@ -457,11 +520,14 @@ int main(int argc, char** argv)
|
|||
if (rc) FAIL(rc);
|
||||
|
||||
{
|
||||
note: update to constructor
|
||||
struct sw_chain c = {
|
||||
.model = &model, .y = switch_to.dest_y,
|
||||
.x = switch_to.dest_x,
|
||||
.start_switch = switch_to.dest_connpt,
|
||||
.from_to = SW_FROM, .max_chain_size = MAX_SW_DEPTH };
|
||||
.from_to = SW_FROM,
|
||||
.max_depth = SW_SET_SIZE,
|
||||
.block_list = 0 };
|
||||
if (fpga_switch_chain(&c) == NO_CONN) FAIL(EINVAL);
|
||||
if (c.set.len == 0) { HERE(); FAIL(EINVAL); }
|
||||
rc = fpga_net_add_switches(&model, P46_net, c.y, c.x, &c.set);
|
||||
|
|
|
@ -734,7 +734,7 @@ static void printf_routing_2minors(uint8_t* bits, int row, int major,
|
|||
if (u64_1 & (1ULL << i))
|
||||
bit_str[i*2+1] = '1';
|
||||
}
|
||||
printf("r%i ma%i v64_%i mip%i %s\n",
|
||||
printf("r%i ma%i v64_%02i mip%02i %s\n",
|
||||
row, major, y, even_minor, bit_str);
|
||||
}
|
||||
}
|
||||
|
|
474
control.c
474
control.c
|
@ -564,9 +564,14 @@ static swidx_t fpga_switch_search(struct fpga_model* model, int y, int x,
|
|||
{
|
||||
struct fpga_tile* tile;
|
||||
int connpt_o, name_i, i;
|
||||
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
connpt_o = SW_I(tile->switches[last], from_to);
|
||||
if (last & FIRST_SW) {
|
||||
connpt_o = fpga_connpt_find(model, y, x, last & ~FIRST_SW,
|
||||
/*dests_o*/ 0, /*num_dests*/ 0);
|
||||
if (connpt_o == NO_CONN) { HERE(); return NO_SWITCH; }
|
||||
} else
|
||||
connpt_o = SW_I(tile->switches[last], from_to);
|
||||
name_i = tile->conn_point_names[connpt_o*2+1];
|
||||
|
||||
for (i = search_beg; i < tile->num_switches; i++) {
|
||||
|
@ -580,7 +585,8 @@ static swidx_t fpga_switch_search(struct fpga_model* model, int y, int x,
|
|||
swidx_t fpga_switch_next(struct fpga_model* model, int y, int x,
|
||||
swidx_t last, int from_to)
|
||||
{
|
||||
return fpga_switch_search(model, y, x, last, last+1, from_to);
|
||||
return fpga_switch_search(model, y, x, last,
|
||||
(last & FIRST_SW) ? 0 : last+1, from_to);
|
||||
}
|
||||
|
||||
swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
|
||||
|
@ -589,6 +595,118 @@ swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
|
|||
return fpga_switch_search(model, y, x, last, /*search_beg*/ 0, from_to);
|
||||
}
|
||||
|
||||
int fpga_swset_fromto(struct fpga_model* model, int y, int x,
|
||||
str16_t start_switch, int from_to, struct sw_set* set)
|
||||
{
|
||||
swidx_t idx;
|
||||
|
||||
set->len = 0;
|
||||
idx = fpga_switch_first(model, y, x, start_switch, from_to);
|
||||
while (idx != NO_SWITCH) {
|
||||
set->sw[set->len++] = idx;
|
||||
idx = fpga_switch_next(model, y, x, idx, from_to);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fpga_swset_contains(struct fpga_model* model, int y, int x,
|
||||
const struct sw_set* set, int from_to, str16_t connpt)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
int i;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
for (i = 0; i < set->len; i++) {
|
||||
if (CONNPT_STR16(tile, SW_I(set->sw[i], from_to)) == connpt)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fpga_swset_remove_connpt(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, int from_to, str16_t connpt)
|
||||
{
|
||||
int i;
|
||||
while ((i = fpga_swset_contains(model, y, x, set,
|
||||
from_to, connpt)) != -1) {
|
||||
if (set->len > i+1)
|
||||
memmove(&set->sw[i], &set->sw[i+1],
|
||||
(set->len-i-1)*sizeof(set->sw[0]));
|
||||
set->len--;
|
||||
}
|
||||
}
|
||||
|
||||
void fpga_swset_remove_loop(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, const struct sw_set* parents, int from_to)
|
||||
{
|
||||
int i;
|
||||
struct fpga_tile* tile;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
for (i = 0; i < parents->len; i++) {
|
||||
fpga_swset_remove_connpt(model, y, x, set, !from_to,
|
||||
CONNPT_STR16(tile, SW_I(parents->sw[i], from_to)));
|
||||
}
|
||||
}
|
||||
|
||||
void fpga_swset_remove_sw(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, swidx_t sw)
|
||||
{
|
||||
int sw_from_connpt, sw_to_connpt, cur_from_connpt, cur_to_connpt, i;
|
||||
|
||||
sw_from_connpt = SW_I(sw, SW_FROM);
|
||||
sw_to_connpt = SW_I(sw, SW_TO);
|
||||
|
||||
for (i = 0; i < set->len; i++) {
|
||||
cur_from_connpt = SW_I(set->sw[i], SW_FROM);
|
||||
cur_to_connpt = SW_I(set->sw[i], SW_TO);
|
||||
if (cur_from_connpt == sw_from_connpt
|
||||
&& cur_to_connpt == sw_to_connpt) {
|
||||
if ((sw & SWITCH_BIDIRECTIONAL)
|
||||
!= (set->sw[i] & SWITCH_BIDIRECTIONAL))
|
||||
HERE();
|
||||
if (set->len > i+1)
|
||||
memmove(&set->sw[i], &set->sw[i+1],
|
||||
(set->len-i-1)*sizeof(set->sw[0]));
|
||||
set->len--;
|
||||
return;
|
||||
}
|
||||
if (cur_from_connpt == sw_to_connpt
|
||||
&& cur_to_connpt == sw_from_connpt)
|
||||
HERE();
|
||||
}
|
||||
}
|
||||
|
||||
int fpga_swset_level_down(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, int from_to)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < set->len) {
|
||||
set->sw[i] = fpga_switch_first(model, y, x,fpga_switch_str_i(
|
||||
model, y, x, set->sw[i], !from_to), from_to);
|
||||
if (set->sw[i] == NO_SWITCH) {
|
||||
if (set->len > i+1)
|
||||
memmove(&set->sw[i], &set->sw[i+1],
|
||||
(set->len-i-1)*sizeof(set->sw[0]));
|
||||
set->len--;
|
||||
} else
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fpga_swset_print(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, int from_to)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < set->len; i++) {
|
||||
printf("swset %i %s\n", i, fpga_switch_print(model,
|
||||
y, x, set->sw[i]));
|
||||
}
|
||||
}
|
||||
|
||||
int fpga_switch_same_fromto(struct fpga_model* model, int y, int x,
|
||||
swidx_t sw, int from_to, swidx_t* same_sw, int *same_len)
|
||||
{
|
||||
|
@ -599,7 +717,7 @@ int fpga_switch_same_fromto(struct fpga_model* model, int y, int x,
|
|||
*same_len = 0;
|
||||
if (max_len < 1) FAIL(EINVAL);
|
||||
cur_sw = fpga_switch_search(model, y, x, sw, /*search_beg*/ 0, from_to);
|
||||
// We should at least fine sw itself, if not something is wrong...
|
||||
// We should at least find sw itself, if not something is wrong...
|
||||
if (cur_sw == NO_SWITCH) FAIL(EINVAL);
|
||||
|
||||
same_sw[(*same_len)++] = cur_sw;
|
||||
|
@ -796,150 +914,262 @@ const char* fmt_swset(struct fpga_model* model, int y, int x,
|
|||
return buf[last_buf];
|
||||
}
|
||||
|
||||
int fpga_switch_chain(struct sw_chain* chain)
|
||||
#undef DBG_ENUM_SWITCH
|
||||
|
||||
int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model,
|
||||
int y, int x, str16_t start_switch, int from_to, int max_depth,
|
||||
swidx_t* block_list, int block_list_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf("construct_sw_chain() %s (%s)\n",
|
||||
strarray_lookup(&model->str, start_switch),
|
||||
(from_to == SW_FROM) ? "SW_FROM" : "SW_TO");
|
||||
#endif
|
||||
memset(chain, 0, sizeof(*chain));
|
||||
chain->model = model;
|
||||
chain->y = y;
|
||||
chain->x = x;
|
||||
chain->from_to = from_to;
|
||||
chain->max_depth = max_depth;
|
||||
if (block_list) {
|
||||
chain->block_list = block_list;
|
||||
chain->block_list_len = block_list_len;
|
||||
// internal_block_list is 0 from memset()
|
||||
} else {
|
||||
chain->internal_block_list = malloc(
|
||||
MAX_SWITCHBOX_SIZE * sizeof(*chain->block_list));
|
||||
if (!chain->internal_block_list)
|
||||
FAIL(ENOMEM);
|
||||
chain->block_list = chain->internal_block_list;
|
||||
chain->block_list_len = 0;
|
||||
}
|
||||
// at every level, the first round returns all members
|
||||
// at that level, then the second round tries to go
|
||||
// one level down for each member. This sorts the
|
||||
// returned switches in a nice way.
|
||||
chain->first_round = 1;
|
||||
chain->set.len = 1;
|
||||
chain->set.sw[0] = FIRST_SW | start_switch;
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void destruct_sw_chain(struct sw_chain* chain)
|
||||
{
|
||||
free(chain->internal_block_list);
|
||||
memset(chain, 0, sizeof(*chain));
|
||||
}
|
||||
|
||||
// returns NO_SWITCH if sw is not found in list, otherwise
|
||||
// the offset in list where it is found.
|
||||
static int switch_list_contains(struct fpga_model* model, int y, int x,
|
||||
swidx_t* list, int list_len, swidx_t sw)
|
||||
{
|
||||
int sw_from_connpt, sw_to_connpt, cur_from_connpt, cur_to_connpt, i;
|
||||
|
||||
sw_from_connpt = SW_I(sw, SW_FROM);
|
||||
sw_to_connpt = SW_I(sw, SW_TO);
|
||||
|
||||
for (i = 0; i < list_len; i++) {
|
||||
cur_from_connpt = SW_I(list[i], SW_FROM);
|
||||
cur_to_connpt = SW_I(list[i], SW_TO);
|
||||
if (cur_from_connpt == sw_from_connpt
|
||||
&& cur_to_connpt == sw_to_connpt) {
|
||||
if ((sw & SWITCH_BIDIRECTIONAL)
|
||||
!= (list[i] & SWITCH_BIDIRECTIONAL))
|
||||
HERE();
|
||||
return i;
|
||||
}
|
||||
if (cur_from_connpt == sw_to_connpt
|
||||
&& cur_to_connpt == sw_from_connpt)
|
||||
HERE();
|
||||
}
|
||||
return NO_SWITCH;
|
||||
}
|
||||
|
||||
int fpga_switch_chain(struct sw_chain* ch)
|
||||
{
|
||||
swidx_t idx;
|
||||
struct fpga_tile* tile;
|
||||
int child_from_to, i;
|
||||
int child_from_to, loop_detect, block_detect, i;
|
||||
|
||||
if (chain->start_switch != STRIDX_NO_ENTRY) {
|
||||
idx = fpga_switch_first(chain->model, chain->y, chain->x,
|
||||
chain->start_switch, chain->from_to);
|
||||
chain->start_switch = STRIDX_NO_ENTRY;
|
||||
if (idx == NO_SWITCH) {
|
||||
HERE(); // unusual and is probably some internal error
|
||||
chain->set.len = 0;
|
||||
return NO_SWITCH;
|
||||
}
|
||||
chain->set.sw[0] = idx;
|
||||
chain->set.len = 1;
|
||||
|
||||
// at every level, the first round returns all members
|
||||
// at that level, then the second round tries to go
|
||||
// one level down for each member. This sorts the
|
||||
// returned switches in a nice way.
|
||||
chain->first_round = 1;
|
||||
chain->prior_parents = 0;
|
||||
chain->num_prior_parents = 0;
|
||||
return 0;
|
||||
}
|
||||
if (!chain->set.len) {
|
||||
HERE(); goto internal_error;
|
||||
}
|
||||
if (chain->first_round) {
|
||||
if (!ch->set.len)
|
||||
{ HERE(); goto internal_error; }
|
||||
if (ch->first_round) {
|
||||
// first go through all members at present level
|
||||
idx = fpga_switch_next(chain->model, chain->y, chain->x,
|
||||
chain->set.sw[chain->set.len-1], chain->from_to);
|
||||
if (idx != NO_SWITCH) {
|
||||
chain->set.sw[chain->set.len-1] = idx;
|
||||
return 0;
|
||||
while (1) {
|
||||
idx = fpga_switch_next(ch->model, ch->y, ch->x,
|
||||
ch->set.sw[ch->set.len-1], ch->from_to);
|
||||
if (idx == NO_SWITCH)
|
||||
break;
|
||||
ch->set.sw[ch->set.len-1] = idx;
|
||||
if (switch_list_contains(ch->model, ch->y, ch->x,
|
||||
ch->block_list, ch->block_list_len, idx)
|
||||
== NO_SWITCH)
|
||||
return 0;
|
||||
}
|
||||
// if there are no more, initiate the second round
|
||||
// looking for children
|
||||
chain->first_round = 0;
|
||||
idx = fpga_switch_backtofirst(chain->model, chain->y, chain->x,
|
||||
chain->set.sw[chain->set.len-1], chain->from_to);
|
||||
// if there are no more, start child round
|
||||
ch->first_round = 0;
|
||||
idx = fpga_switch_backtofirst(ch->model, ch->y, ch->x,
|
||||
ch->set.sw[ch->set.len-1], ch->from_to);
|
||||
if (idx == NO_SWITCH) {
|
||||
HERE(); goto internal_error;
|
||||
}
|
||||
chain->set.sw[chain->set.len-1] = idx;
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf("back_to_first from %s to %s\n",
|
||||
fpga_switch_print(ch->model, ch->y, ch->x,
|
||||
ch->set.sw[ch->set.len-1]),
|
||||
fpga_switch_print(ch->model, ch->y, ch->x,
|
||||
idx));
|
||||
#endif
|
||||
ch->set.sw[ch->set.len-1] = idx;
|
||||
}
|
||||
// look for children
|
||||
tile = YX_TILE(chain->model, chain->y, chain->x);
|
||||
tile = YX_TILE(ch->model, ch->y, ch->x);
|
||||
while (1) {
|
||||
idx = fpga_switch_first(chain->model, chain->y, chain->x,
|
||||
fpga_switch_str_i(chain->model, chain->y, chain->x,
|
||||
chain->set.sw[chain->set.len-1], !chain->from_to),
|
||||
chain->from_to);
|
||||
child_from_to = SW_I(tile->switches[chain->set.sw[chain->set.len-1]],
|
||||
!chain->from_to);
|
||||
idx = fpga_switch_first(ch->model, ch->y, ch->x,
|
||||
fpga_switch_str_i(ch->model, ch->y, ch->x,
|
||||
ch->set.sw[ch->set.len-1], !ch->from_to),
|
||||
ch->from_to);
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf("child_check %s result %s\n", fpga_switch_str(
|
||||
ch->model, ch->y, ch->x,
|
||||
ch->set.sw[ch->set.len-1], !ch->from_to),
|
||||
idx == NO_SWITCH ? "NO_SWITCH" : fpga_switch_print(
|
||||
ch->model, ch->y, ch->x, idx));
|
||||
#endif
|
||||
if (idx != NO_SWITCH) {
|
||||
// If we have the same from-switch already among the
|
||||
// parents, don't fall into endless recursion...
|
||||
for (i = 0; i < chain->set.len; i++) {
|
||||
if (SW_I(tile->switches[chain->set.sw[i]], chain->from_to)
|
||||
== child_from_to)
|
||||
// parents, don't enter into a loop.
|
||||
child_from_to = SW_I(tile->switches[ch->set.sw[
|
||||
ch->set.len-1]], !ch->from_to);
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf(" child_from_to %s\n", connpt_str(
|
||||
ch->model, ch->y, ch->x,
|
||||
child_from_to));
|
||||
#endif
|
||||
loop_detect = 0;
|
||||
for (i = 0; i < ch->set.len; i++) {
|
||||
int parent_connpt = SW_I(tile->switches[
|
||||
ch->set.sw[i]], ch->from_to);
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf(" parent connpt %s%s\n", connpt_str(
|
||||
ch->model, ch->y, ch->x,
|
||||
parent_connpt), parent_connpt
|
||||
== child_from_to ? " (match)" : "");
|
||||
#endif
|
||||
if (parent_connpt == child_from_to) {
|
||||
loop_detect = 1;
|
||||
break;
|
||||
}
|
||||
if (i >= chain->set.len) {
|
||||
if (chain->set.len >= MAX_SW_DEPTH) {
|
||||
HERE(); goto internal_error;
|
||||
}
|
||||
if (chain->max_chain_size < 1
|
||||
|| chain->set.len < chain->max_chain_size) {
|
||||
// back to first round at new level
|
||||
chain->first_round = 1;
|
||||
chain->set.sw[chain->set.len] = idx;
|
||||
chain->set.len++;
|
||||
}
|
||||
block_detect = switch_list_contains(ch->model,
|
||||
ch->y, ch->x, ch->block_list,
|
||||
ch->block_list_len, idx) != NO_SWITCH;
|
||||
if (!loop_detect && !block_detect) {
|
||||
if (ch->set.len >= SW_SET_SIZE)
|
||||
{ HERE(); goto internal_error; }
|
||||
if (ch->max_depth < 1
|
||||
|| ch->set.len < ch->max_depth) {
|
||||
// back to first round at next level
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf(" level_down %s\n",
|
||||
fpga_switch_print(ch->model,
|
||||
ch->y, ch->x, idx));
|
||||
#endif
|
||||
ch->first_round = 1;
|
||||
ch->set.sw[ch->set.len] = idx;
|
||||
ch->set.len++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
chain->set.sw[chain->set.len-1] = fpga_switch_next(
|
||||
chain->model, chain->y, chain->x,
|
||||
chain->set.sw[chain->set.len-1], chain->from_to);
|
||||
if (chain->set.sw[chain->set.len-1] != NO_SWITCH)
|
||||
// todo: don't know why we catch blocklist duplicates
|
||||
// if ch->set.len > 1 - needs more debugging
|
||||
if (switch_list_contains(ch->model, ch->y, ch->x,
|
||||
ch->block_list, ch->block_list_len,
|
||||
ch->set.sw[ch->set.len-1]) == NO_SWITCH) {
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf(" block_list_add %s\n", fpga_switch_print(
|
||||
ch->model, ch->y, ch->x,
|
||||
ch->set.sw[ch->set.len-1]));
|
||||
#endif
|
||||
if (ch->block_list_len >= MAX_SWITCHBOX_SIZE)
|
||||
{ HERE(); goto internal_error; }
|
||||
ch->block_list[ch->block_list_len++]
|
||||
= ch->set.sw[ch->set.len-1];
|
||||
}
|
||||
|
||||
idx = fpga_switch_next(ch->model, ch->y, ch->x,
|
||||
ch->set.sw[ch->set.len-1], ch->from_to);
|
||||
if (idx != NO_SWITCH) {
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf(" found %s\n", fpga_switch_print(
|
||||
ch->model, ch->y, ch->x, idx));
|
||||
#endif
|
||||
ch->set.sw[ch->set.len-1] = idx;
|
||||
break;
|
||||
if (chain->set.len <= 1) {
|
||||
chain->set.len = 0;
|
||||
}
|
||||
|
||||
if (ch->set.len <= 1) {
|
||||
ch->set.len = 0;
|
||||
return NO_SWITCH;
|
||||
}
|
||||
chain->set.len--;
|
||||
#ifdef DBG_ENUM_SWITCH
|
||||
printf(" level_up\n");
|
||||
#endif
|
||||
ch->set.len--;
|
||||
}
|
||||
}
|
||||
internal_error:
|
||||
chain->set.len = 0;
|
||||
ch->set.len = 0;
|
||||
return NO_SWITCH;
|
||||
}
|
||||
|
||||
int fpga_switch_chains(struct sw_chain* chain, int max_sets,
|
||||
struct sw_set* sets, int* num_sets)
|
||||
int construct_sw_conns(struct sw_conns* conns, struct fpga_model* model,
|
||||
int y, int x, str16_t start_switch, int from_to, int max_depth)
|
||||
{
|
||||
*num_sets = 0;
|
||||
while (*num_sets < max_sets
|
||||
&& fpga_switch_chain(chain) != NO_CONN) {
|
||||
sets[*num_sets] = chain->set;
|
||||
}
|
||||
memset(conns, 0, sizeof(*conns));
|
||||
construct_sw_chain(&conns->chain, model, y, x, start_switch,
|
||||
from_to, max_depth, /*block_list*/ 0, /*block_list_len*/ 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void destruct_sw_conns(struct sw_conns* conns)
|
||||
{
|
||||
destruct_sw_chain(&conns->chain);
|
||||
memset(conns, 0, sizeof(*conns));
|
||||
}
|
||||
|
||||
int fpga_switch_conns(struct sw_conns* conns)
|
||||
{
|
||||
str16_t end_of_chain_str;
|
||||
|
||||
if (conns->start_switch != STRIDX_NO_ENTRY) {
|
||||
conns->chain.model = conns->model;
|
||||
conns->chain.y = conns->y;
|
||||
conns->chain.x = conns->x;
|
||||
conns->chain.start_switch = conns->start_switch;
|
||||
conns->chain.from_to = conns->from_to;
|
||||
conns->chain.max_chain_size = conns->max_switch_depth;
|
||||
|
||||
conns->start_switch = STRIDX_NO_ENTRY;
|
||||
conns->num_dests = 0;
|
||||
conns->dest_i = 0;
|
||||
}
|
||||
else if (!conns->chain.set.len) { HERE(); goto internal_error; }
|
||||
if (!conns->chain.set.len) { HERE(); goto internal_error; }
|
||||
|
||||
// on the first call, both dest_i and num_dests are 0
|
||||
while (conns->dest_i >= conns->num_dests) {
|
||||
fpga_switch_chain(&conns->chain);
|
||||
if (conns->chain.set.len == 0)
|
||||
return NO_CONN;
|
||||
end_of_chain_str = fpga_switch_str_i(conns->model,
|
||||
conns->y, conns->x,
|
||||
end_of_chain_str = fpga_switch_str_i(conns->chain.model,
|
||||
conns->chain.y, conns->chain.x,
|
||||
conns->chain.set.sw[conns->chain.set.len-1],
|
||||
!conns->from_to);
|
||||
!conns->chain.from_to);
|
||||
if (end_of_chain_str == STRIDX_NO_ENTRY)
|
||||
{ HERE(); goto internal_error; }
|
||||
conns->dest_i = 0;
|
||||
fpga_connpt_find(conns->model, conns->y, conns->x,
|
||||
end_of_chain_str, &conns->connpt_dest_start,
|
||||
&conns->num_dests);
|
||||
fpga_connpt_find(conns->chain.model, conns->chain.y,
|
||||
conns->chain.x, end_of_chain_str,
|
||||
&conns->connpt_dest_start, &conns->num_dests);
|
||||
if (conns->num_dests)
|
||||
break;
|
||||
}
|
||||
fpga_conn_dest(conns->model, conns->y, conns->x,
|
||||
fpga_conn_dest(conns->chain.model, conns->chain.y, conns->chain.x,
|
||||
conns->connpt_dest_start + conns->dest_i,
|
||||
&conns->dest_y, &conns->dest_x, &conns->dest_str_i);
|
||||
if (conns->dest_str_i == STRIDX_NO_ENTRY)
|
||||
|
@ -953,45 +1183,58 @@ internal_error:
|
|||
}
|
||||
|
||||
void printf_swchain(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int from_to, int max_depth)
|
||||
str16_t sw, int from_to, int max_depth, swidx_t* block_list,
|
||||
int* block_list_len)
|
||||
{
|
||||
struct sw_chain chain =
|
||||
{ .model = model, .y = y, .x = x, .start_switch = sw,
|
||||
.from_to = from_to, .max_chain_size = max_depth};
|
||||
struct sw_chain chain;
|
||||
int count = 0;
|
||||
|
||||
printf("printf_swchain() y%02i x%02i %s blist_len %i\n",
|
||||
y, x, strarray_lookup(&model->str, sw),
|
||||
block_list_len ? *block_list_len : 0);
|
||||
if (construct_sw_chain(&chain, model, y, x, sw, from_to, max_depth,
|
||||
block_list, block_list_len ? *block_list_len : 0))
|
||||
{ HERE(); return; }
|
||||
while (fpga_switch_chain(&chain) != NO_CONN) {
|
||||
printf("sw %s\n", fmt_swset(model, y, x,
|
||||
printf("sw %i %s\n", count++, fmt_swset(model, y, x,
|
||||
&chain.set, from_to));
|
||||
}
|
||||
printf("sw - block_list_len %i\n", chain.block_list_len);
|
||||
if (block_list_len)
|
||||
*block_list_len = chain.block_list_len;
|
||||
destruct_sw_chain(&chain);
|
||||
}
|
||||
|
||||
void printf_swconns(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int from_to, int max_depth)
|
||||
{
|
||||
struct sw_conns conns =
|
||||
{ .model = model, .y = y, .x = x, .start_switch = sw,
|
||||
.from_to = from_to, .max_switch_depth = max_depth };
|
||||
struct sw_conns conns;
|
||||
|
||||
if (construct_sw_conns(&conns, model, y, x, sw, from_to, max_depth))
|
||||
{ HERE(); return; }
|
||||
while (fpga_switch_conns(&conns) != NO_CONN) {
|
||||
printf("sw %s conn y%02i x%02i %s\n", fmt_swset(model, y, x,
|
||||
&conns.chain.set, from_to),
|
||||
conns.dest_y, conns.dest_x,
|
||||
strarray_lookup(&model->str, conns.dest_str_i));
|
||||
}
|
||||
printf("sw -\n");
|
||||
destruct_sw_conns(&conns);
|
||||
}
|
||||
|
||||
int fpga_switch_to_yx(struct switch_to_yx* p)
|
||||
{
|
||||
struct sw_conns conns = {
|
||||
.model = p->model, .y = p->y, .x = p->x,
|
||||
.start_switch = p->start_switch, .from_to = p->from_to,
|
||||
.max_switch_depth =
|
||||
(p->flags & SWTO_YX_MAX_SWITCH_DEPTH)
|
||||
? p->max_switch_depth : MAX_SW_DEPTH };
|
||||
|
||||
struct sw_conns conns;
|
||||
struct sw_set best_set;
|
||||
int best_y, best_x, best_distance, distance;
|
||||
int best_num_dests;
|
||||
int best_num_dests, rc;
|
||||
str16_t best_connpt;
|
||||
|
||||
rc = construct_sw_conns(&conns, p->model, p->y, p->x, p->start_switch,
|
||||
p->from_to, (p->flags & SWTO_YX_MAX_SWITCH_DEPTH)
|
||||
? p->max_switch_depth : SW_SET_SIZE);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
best_y = -1;
|
||||
while (fpga_switch_conns(&conns) != NO_CONN) {
|
||||
if (is_atyx(p->yx_req, p->model, conns.dest_y, conns.dest_x)) {
|
||||
|
@ -1027,7 +1270,10 @@ int fpga_switch_to_yx(struct switch_to_yx* p)
|
|||
p->dest_x = best_x;
|
||||
p->dest_connpt = best_connpt;
|
||||
}
|
||||
destruct_sw_conns(&conns);
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void printf_switch_to_result(struct switch_to_yx* p)
|
||||
|
|
82
control.h
82
control.h
|
@ -63,11 +63,15 @@ 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
|
||||
#define MAX_SW_DEPTH 64 // largest seen so far was 20
|
||||
// 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
|
||||
|
||||
struct sw_set
|
||||
{
|
||||
swidx_t sw[MAX_SW_DEPTH];
|
||||
swidx_t sw[SW_SET_SIZE];
|
||||
int len;
|
||||
};
|
||||
|
||||
|
@ -78,6 +82,25 @@ swidx_t fpga_switch_next(struct fpga_model* model, int y, int x,
|
|||
swidx_t last, int from_to);
|
||||
swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
|
||||
swidx_t last, int from_to);
|
||||
|
||||
int fpga_swset_fromto(struct fpga_model* model, int y, int x,
|
||||
str16_t start_switch, int from_to, struct sw_set* set);
|
||||
// returns -1 if not found, otherwise index into the set
|
||||
int fpga_swset_contains(struct fpga_model* model, int y, int x,
|
||||
const struct sw_set* set, int from_to, str16_t connpt);
|
||||
void fpga_swset_remove_connpt(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, int from_to, str16_t connpt);
|
||||
// removes all switches from set whose !from_to is equal to the
|
||||
// from_to in parents
|
||||
void fpga_swset_remove_loop(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, const struct sw_set* parents, int from_to);
|
||||
void fpga_swset_remove_sw(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, swidx_t sw);
|
||||
int fpga_swset_level_down(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, int from_to);
|
||||
void fpga_swset_print(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, int from_to);
|
||||
|
||||
// When calling, same_len must contain the size of the
|
||||
// same_sw array. Upon return same_len returns how many
|
||||
// switches were found and writen to same_sw.
|
||||
|
@ -106,9 +129,10 @@ void fpga_switch_disable(struct fpga_model* model, int y, int x,
|
|||
const char* fmt_swset(struct fpga_model* model, int y, int x,
|
||||
struct sw_set* set, int from_to);
|
||||
|
||||
// MAX_PRIOR_PARENTS should be larger than the largest known
|
||||
// numer of switches in a tile, currently 3459 in a slx9 routing tile.
|
||||
#define MAX_PRIOR_PARENTS 4000
|
||||
// MAX_SWITCHBOX_SIZE can be used to allocate the block
|
||||
// list and should be larger than the largest known number
|
||||
// of switches in a tile, currently 3459 in a slx9 routing tile.
|
||||
#define MAX_SWITCHBOX_SIZE 4000
|
||||
|
||||
struct sw_chain
|
||||
{
|
||||
|
@ -116,41 +140,40 @@ struct sw_chain
|
|||
struct fpga_model* model;
|
||||
int y;
|
||||
int x;
|
||||
// start_switch will be set to STRIDX_NO_ENTRY (0) after the first call
|
||||
str16_t start_switch;
|
||||
int from_to;
|
||||
int max_chain_size;
|
||||
int max_depth;
|
||||
//
|
||||
// block_list works as if all switches from or to the ones
|
||||
// on the block list are blocked, that is the recursion will
|
||||
// never step into a part of the tree that goes through a
|
||||
// blocked from or to point.
|
||||
// Every call to fpga_switch_chain(), even the last one that
|
||||
// returns NO_SWITCH, may add switches to the block list.
|
||||
//
|
||||
swidx_t* block_list;
|
||||
int block_list_len;
|
||||
|
||||
// return values:
|
||||
// return value: set is carried forward through the
|
||||
// enumeration and must only be read from.
|
||||
struct sw_set set;
|
||||
|
||||
// internal:
|
||||
int first_round;
|
||||
swidx_t* prior_parents;
|
||||
int num_prior_parents;
|
||||
swidx_t* internal_block_list;
|
||||
};
|
||||
|
||||
int construct_sw_chain(struct sw_chain* chain, struct fpga_model* model,
|
||||
int y, int x, str16_t start_switch, int from_to, int max_depth,
|
||||
swidx_t* block_list, int block_list_len);
|
||||
void destruct_sw_chain(struct sw_chain* chain);
|
||||
|
||||
// Returns 0 if another switchset is returned in chain, or
|
||||
// NO_SWITCH (-1) if there is no other switchset.
|
||||
// chain_size set to 0 when there are no more switches in the tree
|
||||
// set.len is 0 when there are no more switches in the tree
|
||||
int fpga_switch_chain(struct sw_chain* chain);
|
||||
|
||||
// returns error code or 0 for no errors
|
||||
int fpga_switch_chains(struct sw_chain* chain, int max_sets,
|
||||
struct sw_set* sets, int* num_sets);
|
||||
|
||||
struct sw_conns
|
||||
{
|
||||
// start and recurring values:
|
||||
struct fpga_model* model;
|
||||
int y;
|
||||
int x;
|
||||
// start_switch will be set to STRIDX_NO_ENTRY (0) after first call
|
||||
str16_t start_switch;
|
||||
int from_to;
|
||||
int max_switch_depth;
|
||||
|
||||
// return values:
|
||||
struct sw_chain chain;
|
||||
int connpt_dest_start;
|
||||
int num_dests;
|
||||
|
@ -160,12 +183,17 @@ struct sw_conns
|
|||
str16_t dest_str_i;
|
||||
};
|
||||
|
||||
int construct_sw_conns(struct sw_conns* conns, struct fpga_model* model,
|
||||
int y, int x, str16_t start_switch, int from_to, int max_depth);
|
||||
void destruct_sw_conns(struct sw_conns* conns);
|
||||
|
||||
// Returns 0 if another connection is returned in conns, or
|
||||
// NO_CONN (-1) if there is no other connection.
|
||||
int fpga_switch_conns(struct sw_conns* conns);
|
||||
|
||||
void printf_swchain(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int from_to, int max_depth);
|
||||
str16_t sw, int from_to, int max_depth, swidx_t* block_list,
|
||||
int* block_list_len);
|
||||
void printf_swconns(struct fpga_model* model, int y, int x,
|
||||
str16_t sw, int from_to, int max_depth);
|
||||
|
||||
|
|
6
model.h
6
model.h
|
@ -481,8 +481,14 @@ struct fpga_device
|
|||
#define SW_TO 0
|
||||
|
||||
#define NO_SWITCH -1
|
||||
// FIRST_SW must be high enough to be above switch indices or
|
||||
// connpt or str16.
|
||||
#define FIRST_SW 0x80000
|
||||
#define NO_CONN -1
|
||||
|
||||
typedef int connpt_t; // index into conn_point_names (not yet *2)
|
||||
#define CONNPT_STR16(tile, connpt) ((tile)->conn_point_names[(connpt)*2+1])
|
||||
|
||||
struct fpga_tile
|
||||
{
|
||||
enum fpga_tile_type type;
|
||||
|
|
Loading…
Reference in New Issue
Block a user