what a mess, this can only be the first step...

This commit is contained in:
Wolfgang Spraul 2012-08-30 05:37:42 +02:00
parent c852442ad3
commit 05fe89cb9d
5 changed files with 517 additions and 171 deletions

View File

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

View File

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

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

View File

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

View File

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