From e4c9a8f5c7b7254703221ebbd6babce7090b2308 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Thu, 2 Aug 2012 10:58:56 +0200 Subject: [PATCH] a little switch infrastructure --- model.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ model.h | 2 ++ new_fp.c | 35 +++++++++++++++++++++- 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/model.c b/model.c index 558ab3f..f4198d9 100644 --- a/model.c +++ b/model.c @@ -57,6 +57,9 @@ struct w_net static int add_conn_net(struct fpga_model* model, add_conn_f add_conn_func, struct w_net* net); +static int add_switch(struct fpga_model* model, int y, int x, const char* from, + const char* to, int is_bidirectional); + struct seed_data { int x_flags; @@ -108,7 +111,24 @@ void fpga_free_model(struct fpga_model* model) static int init_switches(struct fpga_model* model) { + int x, y, rc; + + for (x = 0; x < model->x_width; x++) { + if (!is_atx(X_ROUTING_COL, model, x)) + continue; + for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) { + if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, + model, y)) + continue; + + if (y != 68 || x != 12) continue; + rc = add_switch(model, y, x, "LOGICOUT0", "NN2B0", 0 /* bidir */); + if (rc) goto xout; + } + } return 0; +xout: + return rc; } static int init_devices(struct fpga_model* model) @@ -2228,6 +2248,76 @@ xout: return rc; } +#define SWITCH_ALLOC_INCREMENT 64 + +static int add_switch(struct fpga_model* model, int y, int x, const char* from, + const char* to, int is_bidirectional) +{ + struct fpga_tile* tile = YX_TILE(model, y, x); + int rc, i, from_idx, to_idx, from_connpt_o, to_connpt_o; + uint32_t new_switch; + + rc = strarray_find(&model->str, from, &from_idx); + if (rc) goto xout; + rc = strarray_find(&model->str, to, &to_idx); + if (rc) goto xout; + if (from_idx == STRIDX_NO_ENTRY || to_idx == STRIDX_NO_ENTRY) { + fprintf(stderr, "No string for switch from %s (%i) or %s (%i).\n", + from, from_idx, to, to_idx); + return -1; + } + + from_connpt_o = -1; + for (i = 0; i < tile->num_conn_point_names; i++) { + if (tile->conn_point_names[i*2+1] == from_idx) { + from_connpt_o = i; + break; + } + } + to_connpt_o = -1; + for (i = 0; i < tile->num_conn_point_names; i++) { + if (tile->conn_point_names[i*2+1] == to_idx) { + to_connpt_o = i; + break; + } + } + if (from_connpt_o == -1 || to_connpt_o == -1) { + fprintf(stderr, "No conn point for switch from %s (%i/%i) or %s (%i/%i).\n", + from, from_idx, from_connpt_o, to, to_idx, to_connpt_o); + return -1; + } + if (from_connpt_o > SWITCH_MAX_CONNPT_O + || to_connpt_o > SWITCH_MAX_CONNPT_O) { + fprintf(stderr, "Internal error in %s:%i (from_o %i to_o %i)\n", + __FILE__, __LINE__, from_connpt_o, to_connpt_o); + return -1; + } + new_switch = (from_connpt_o << 15) | to_connpt_o; + if (is_bidirectional) + new_switch |= SWITCH_BIDIRECTIONAL; + + for (i = 0; i < tile->num_switches; i++) { + if ((tile->switches[i] & 0x3FFFFFFF) == (new_switch & 0x3FFFFFFF)) { + fprintf(stderr, "Internal error in %s:%i duplicate switch from %s to %s\n", + __FILE__, __LINE__, from, to); + return -1; + } + } + if (!(tile->num_switches % SWITCH_ALLOC_INCREMENT)) { + uint32_t* new_ptr = realloc(tile->switches, + (tile->num_switches+SWITCH_ALLOC_INCREMENT)*sizeof(*tile->switches)); + if (!new_ptr) { + fprintf(stderr, "Out of memory %s:%i\n", __FILE__, __LINE__); + return -1; + } + tile->switches = new_ptr; + } + tile->switches[tile->num_switches++] = new_switch; + return 0; +xout: + return rc; +} + static void seed_strx(struct fpga_model* model, struct seed_data* data) { int x, i; diff --git a/model.h b/model.h index 7457127..e81da95 100644 --- a/model.h +++ b/model.h @@ -269,7 +269,9 @@ struct fpga_device }; }; +#define SWITCH_ON 0x80000000 #define SWITCH_BIDIRECTIONAL 0x40000000 +#define SWITCH_MAX_CONNPT_O 0x7FFF // 15 bits struct fpga_tile { diff --git a/new_fp.c b/new_fp.c index 3881c38..2b10e0e 100644 --- a/new_fp.c +++ b/new_fp.c @@ -264,6 +264,39 @@ int printf_conns(struct fpga_model* model) int printf_switches(struct fpga_model* model) { - // switch y01 x02 from direction(->|<->) to + struct fpga_tile* tile; + int x, y, i, from_connpt_o, to_connpt_o, from_str_i, to_str_i; + int first_switch_printed, is_bidirectional; + const char* from_str, *to_str; + + for (x = 0; x < model->x_width; x++) { + for (y = 0; y < model->y_height; y++) { + tile = YX_TILE(model, y, x); + + first_switch_printed = 0; + for (i = 0; i < tile->num_switches; i++) { + from_connpt_o = (tile->switches[i] & 0x3FFF8000) >> 15; + to_connpt_o = tile->switches[i] & 0x00007FFF; + is_bidirectional = (tile->switches[i] & SWITCH_BIDIRECTIONAL) != 0; + + from_str_i = tile->conn_point_names[from_connpt_o*2+1]; + to_str_i = tile->conn_point_names[to_connpt_o*2+1]; + + from_str = strarray_lookup(&model->str, from_str_i); + to_str = strarray_lookup(&model->str, to_str_i); + if (!from_str || !to_str) { + fprintf(stderr, "Internal error in %s:%i, cannot lookup from_i %i or to_i %i\n", + __FILE__, __LINE__, from_str_i, to_str_i); + continue; + } + if (!first_switch_printed) { + first_switch_printed = 1; + printf("\n"); + } + printf("switch y%02i x%02i %s %s %s\n", y, x, from_str, + is_bidirectional ? "<->" : "->", to_str); + } + } + } return 0; }