a little switch infrastructure

This commit is contained in:
Wolfgang Spraul 2012-08-02 10:58:56 +02:00
parent 7148b17d4b
commit e4c9a8f5c7
3 changed files with 126 additions and 1 deletions

90
model.c
View File

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

View File

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

View File

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