diff --git a/autotest.c b/autotest.c index a276572..b16d8c5 100644 --- a/autotest.c +++ b/autotest.c @@ -103,25 +103,6 @@ fail: return rc; } -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 }; - while (fpga_switch_conns(&conns) != NO_CONN) { - if (is_atyx(p->yx_req, p->model, conns.dest_y, conns.dest_x)) { - memcpy(p->chain, conns.chain.chain, - conns.chain.chain_size*sizeof(*p->chain)); - p->chain_size = conns.chain.chain_size; - p->dest_y = conns.dest_y; - p->dest_x = conns.dest_x; - p->dest_connpt = conns.dest_str_i; - return 0; - } - } - p->chain_size = 0; - return 0; -} - int main(int argc, char** argv) { struct fpga_model model; @@ -189,6 +170,7 @@ int main(int argc, char** argv) printf("P46 I pinw %s\n", strarray_lookup(&model.str, P46_dev->iob.pinw_out_I)); switch_to.yx_req = YX_DEV_ILOGIC; + switch_to.flags = SWTO_YX_DEF; switch_to.model = &model; switch_to.y = P46_y; switch_to.x = P46_x; @@ -198,6 +180,7 @@ int main(int argc, char** argv) printf("%s\n", fmt_swchain(&model, switch_to.y, switch_to.x, switch_to.chain, switch_to.chain_size)); switch_to.yx_req = YX_ROUTING_TILE; + switch_to.flags = SWTO_YX_DEF; switch_to.y = switch_to.dest_y; switch_to.x = switch_to.dest_x; switch_to.start_switch = switch_to.dest_connpt; @@ -206,6 +189,7 @@ int main(int argc, char** argv) printf("%s\n", fmt_swchain(&model, switch_to.y, switch_to.x, switch_to.chain, switch_to.chain_size)); switch_to.yx_req = YX_ROUTING_TO_FABLOGIC; + switch_to.flags = SWTO_YX_CLOSEST; switch_to.y = switch_to.dest_y; switch_to.x = switch_to.dest_x; switch_to.start_switch = switch_to.dest_connpt; @@ -213,8 +197,7 @@ int main(int argc, char** argv) if (rc) FAIL(rc); printf("%s\n", fmt_swchain(&model, switch_to.y, switch_to.x, switch_to.chain, switch_to.chain_size)); - // todo: result is NN2 but NR1 would be closer - // printf_swconns(&model, P46_y, P46_x, P46_dev->iob.pinw_out_I); + // next: YX_DEV_LOGIC printf("P48 O pinw %s\n", strarray_lookup(&model.str, P48_dev->iob.pinw_in_O)); diff --git a/control.c b/control.c index 7c2bc7f..1bc9006 100644 --- a/control.c +++ b/control.c @@ -619,3 +619,51 @@ void printf_swconns(struct fpga_model* model, int y, int x, str16_t sw) strarray_lookup(&model->str, conns.dest_str_i)); } } + +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 }; + + int best_y, best_x, best_chain_size, best_distance, distance; + int best_num_dests; + str16_t best_connpt; + swidx_t best_chain[MAX_SW_CHAIN_SIZE]; + + best_y = -1; + while (fpga_switch_conns(&conns) != NO_CONN) { + if (is_atyx(p->yx_req, p->model, conns.dest_y, conns.dest_x)) { + if (best_y != -1) { + distance = abs(conns.dest_y-p->y) + +abs(conns.dest_x-p->x); + if (distance > best_distance) + continue; + else if (conns.num_dests > best_num_dests) + continue; + else if (conns.chain.chain_size > best_chain_size) + continue; + } + memcpy(best_chain, conns.chain.chain, + conns.chain.chain_size*sizeof(*best_chain)); + best_chain_size = conns.chain.chain_size; + best_y = conns.dest_y; + best_x = conns.dest_x; + best_num_dests = conns.num_dests; + best_connpt = conns.dest_str_i; + best_distance = abs(conns.dest_y-p->y) + +abs(conns.dest_x-p->x); + if (!p->flags & SWTO_YX_CLOSEST) + break; + } + } + if (best_y == -1) + p->chain_size = 0; + else { + memcpy(p->chain, best_chain, best_chain_size*sizeof(*p->chain)); + p->chain_size = best_chain_size; + p->dest_y = best_y; + p->dest_x = best_x; + p->dest_connpt = best_connpt; + } + return 0; +} diff --git a/control.h b/control.h index ac00a54..8e15ef6 100644 --- a/control.h +++ b/control.h @@ -41,6 +41,7 @@ void fpga_conn_dest(struct fpga_model* model, int y, int x, int connpt_dest_idx, int* dest_y, int* dest_x, str16_t* str_i); typedef int swidx_t; // swidx_t is an index into the uint32_t switches array +#define MAX_SW_CHAIN_SIZE 32 // largest seen so far was 10 // returns a switch index, or -1 (NO_SWITCH) if no switch was found swidx_t fpga_switch_first(struct fpga_model* model, int y, int x, @@ -68,8 +69,6 @@ const char* fmt_sw(struct fpga_model* model, int y, int x, const char* fmt_swchain(struct fpga_model* model, int y, int x, swidx_t* sw, int sw_size); -#define MAX_SW_CHAIN_SIZE 32 // largest seen so far was 10 - struct sw_chain { // start and recurring values: @@ -118,10 +117,14 @@ int fpga_switch_conns(struct sw_conns* conns); void printf_swconns(struct fpga_model* model, int y, int x, str16_t sw); +#define SWTO_YX_DEF 0 +#define SWTO_YX_CLOSEST 0x0001 + struct switch_to_yx { // input: int yx_req; // YX_-value + int flags; // SWTO_YX-value struct fpga_model* model; int y; int x;