autotest, minor fixes all over
This commit is contained in:
parent
63f16c95d0
commit
a88c4f1835
6
Makefile
6
Makefile
|
@ -10,6 +10,12 @@ PREFIX ?= /usr/local
|
||||||
|
|
||||||
.PHONY: all clean install uninstall
|
.PHONY: all clean install uninstall
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
|
|
||||||
|
# -fno-omit-frame-pointer and -ggdb add almost nothing to execution
|
||||||
|
# time right now, so we can leave them in all the time.
|
||||||
|
CFLAGS_DBG = -fno-omit-frame-pointer -ggdb
|
||||||
|
CFLAGS += $(CFLAGS_DBG)
|
||||||
|
|
||||||
CFLAGS += -Wall -Wshadow -Wmissing-prototypes -Wmissing-declarations \
|
CFLAGS += -Wall -Wshadow -Wmissing-prototypes -Wmissing-declarations \
|
||||||
-Wno-format-zero-length -Ofast
|
-Wno-format-zero-length -Ofast
|
||||||
CFLAGS += `pkg-config libxml-2.0 --cflags`
|
CFLAGS += `pkg-config libxml-2.0 --cflags`
|
||||||
|
|
100
autotest.c
100
autotest.c
|
@ -110,8 +110,10 @@ static int printf_switchtree(struct fpga_model* model, int y, int x,
|
||||||
{
|
{
|
||||||
int i, idx, conn_to_y, conn_to_x, num_dests, connpt_dests_o, rc;
|
int i, idx, conn_to_y, conn_to_x, num_dests, connpt_dests_o, rc;
|
||||||
const char* to_str;
|
const char* to_str;
|
||||||
|
char tmp_str[128];
|
||||||
|
|
||||||
printf("%.*sy%02i x%02i %s\n", indent, s_spaces, y, x, start);
|
// printf("%.*sy%02i x%02i %s\n", indent, s_spaces, y, x, start);
|
||||||
|
#if 0
|
||||||
num_dests = fpga_connpt_lookup(model, y, x, start, &connpt_dests_o);
|
num_dests = fpga_connpt_lookup(model, y, x, start, &connpt_dests_o);
|
||||||
for (i = 0; i < num_dests; i++) {
|
for (i = 0; i < num_dests; i++) {
|
||||||
if (!i)
|
if (!i)
|
||||||
|
@ -132,16 +134,22 @@ static int printf_switchtree(struct fpga_model* model, int y, int x,
|
||||||
to_str);
|
to_str);
|
||||||
idx = fpga_switch_next(model, y, x, idx, SW_TO);
|
idx = fpga_switch_next(model, y, x, idx, SW_TO);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
idx = fpga_switch_first(model, y, x, start, SW_FROM);
|
idx = fpga_switch_first(model, y, x, start, SW_FROM);
|
||||||
if (idx != NO_SWITCH)
|
if (idx != NO_SWITCH)
|
||||||
printf("%.*s| switches to:\n", indent, s_spaces);
|
printf("%.*s| switches to:\n", indent, s_spaces);
|
||||||
while (idx != NO_SWITCH) {
|
while (idx != NO_SWITCH) {
|
||||||
|
printf("%.*s %s\n", indent, s_spaces,
|
||||||
|
fmt_sw(model, y, x, idx, SW_FROM));
|
||||||
to_str = fpga_switch_str(model, y, x, idx, SW_TO);
|
to_str = fpga_switch_str(model, y, x, idx, SW_TO);
|
||||||
|
#if 0
|
||||||
printf("%.*s %s %s\n", indent, s_spaces,
|
printf("%.*s %s %s\n", indent, s_spaces,
|
||||||
fpga_switch_is_bidir(model, y, x, idx) ? "<->" : "->",
|
fpga_switch_is_bidir(model, y, x, idx) ? "<->" : "->",
|
||||||
to_str);
|
to_str);
|
||||||
rc = printf_switchtree(model, y, x, to_str, indent+2);
|
#endif
|
||||||
|
strcpy(tmp_str, to_str);
|
||||||
|
rc = printf_switchtree(model, y, x, tmp_str, indent+2);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
idx = fpga_switch_next(model, y, x, idx, SW_FROM);
|
idx = fpga_switch_next(model, y, x, idx, SW_FROM);
|
||||||
}
|
}
|
||||||
|
@ -150,15 +158,46 @@ fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printf_swconns(struct fpga_model* model, int y, int x, const char* sw)
|
||||||
|
{
|
||||||
|
struct swchain_conns conns =
|
||||||
|
{ .model = model, .y = y, .x = x, .start_switch = sw };
|
||||||
|
while (fpga_switch_conns_enum(&conns) != NO_CONN) {
|
||||||
|
printf("sw %s conn y%02i x%02i %s\n", fmt_swchain(model, y, x,
|
||||||
|
conns.chain.chain, conns.chain.chain_size),
|
||||||
|
conns.dest_y, conns.dest_x, conns.dest_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return dest_y, dest_x, dest_str
|
||||||
|
int fpga_switch_to_yx(int yx_req, struct fpga_model* model, int y, int x,
|
||||||
|
const char* start_switch, swidx_t* sw_chain, int* sw_chain_size)
|
||||||
|
{
|
||||||
|
struct swchain_conns conns = { .model = model, .y = y, .x = x,
|
||||||
|
.start_switch = start_switch };
|
||||||
|
while (fpga_switch_conns_enum(&conns) != NO_CONN) {
|
||||||
|
if (is_atyx(yx_req, model, conns.dest_y, conns.dest_x)) {
|
||||||
|
memcpy(sw_chain, conns.chain.chain,
|
||||||
|
conns.chain.chain_size*sizeof(*sw_chain));
|
||||||
|
*sw_chain_size = conns.chain.chain_size;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*sw_chain_size = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
struct fpga_model model;
|
struct fpga_model model;
|
||||||
struct fpga_device* P46_dev, *P48_dev, *logic_dev;
|
struct fpga_device* P46_dev, *P48_dev, *logic_dev;
|
||||||
int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, rc;
|
int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, rc;
|
||||||
struct test_state tstate;
|
struct test_state tstate;
|
||||||
struct sw_chain chain;
|
// struct sw_chain chain;
|
||||||
struct swchain_conns conns;
|
// struct swchain_conns conns;
|
||||||
char tmp_str[128];
|
char tmp_str[128];
|
||||||
|
swidx_t switch_chain[MAX_SW_CHAIN_SIZE];
|
||||||
|
int switch_chain_size;
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("O fpgatools automatic test suite. Be welcome and be "
|
printf("O fpgatools automatic test suite. Be welcome and be "
|
||||||
|
@ -214,16 +253,28 @@ int main(int argc, char** argv)
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
rc = diff_printf(&tstate);
|
rc = diff_printf(&tstate);
|
||||||
if (rc) goto fail;
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
rc = fpga_switch_to_yx(YX_DEV_ILOGIC, &model, P46_y, P46_x,
|
||||||
|
P46_dev->iob.pinw_out_I, switch_chain, &switch_chain_size);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
// todo: needs to return dest_y, dest_x, dest_connpt
|
||||||
|
|
||||||
|
printf("%s\n", fmt_swchain(&model, P46_y, P46_x, switch_chain, switch_chain_size));
|
||||||
|
|
||||||
|
#if 0
|
||||||
printf("P46 I pinw %s\n", P46_dev->iob.pinw_out_I);
|
printf("P46 I pinw %s\n", P46_dev->iob.pinw_out_I);
|
||||||
|
|
||||||
|
printf_swconns(&model, P46_y, P46_x, P46_dev->iob.pinw_out_I);
|
||||||
|
|
||||||
|
|
||||||
conns.model = &model;
|
conns.model = &model;
|
||||||
conns.y = P46_y;
|
conns.y = P46_y;
|
||||||
conns.x = P46_x;
|
conns.x = P46_x;
|
||||||
conns.start_switch = P46_dev->iob.pinw_out_I;
|
conns.start_switch = P46_dev->iob.pinw_out_I;
|
||||||
while (fpga_switch_conns_enum(&conns) != NO_CONN) {
|
while (fpga_switch_conns_enum(&conns) != NO_CONN) {
|
||||||
|
|
||||||
if (is_aty(Y_TOP_INNER_IO|Y_BOT_INNER_IO, &model, conns.dest_y)) {
|
if (is_atyx(YX_DEV_ILOGIC, &model, conns.dest_y, conns.dest_x)) {
|
||||||
struct swchain_conns conns2;
|
struct swchain_conns conns2;
|
||||||
|
|
||||||
printf("conn chain_size %i connpt_o %i num_dests %i i %i y %i x %i str %s\n",
|
printf("conn chain_size %i connpt_o %i num_dests %i i %i y %i x %i str %s\n",
|
||||||
|
@ -235,55 +286,36 @@ int main(int argc, char** argv)
|
||||||
conns2.y = conns.dest_y;
|
conns2.y = conns.dest_y;
|
||||||
conns2.x = conns.dest_x;
|
conns2.x = conns.dest_x;
|
||||||
conns2.start_switch = tmp_str;
|
conns2.start_switch = tmp_str;
|
||||||
|
|
||||||
while (fpga_switch_conns_enum(&conns2) != NO_CONN) {
|
while (fpga_switch_conns_enum(&conns2) != NO_CONN) {
|
||||||
if (is_atyx(YX_ROUTING_TILE, &model, conns2.dest_y, conns2.dest_x)) {
|
if (is_atyx(YX_ROUTING_TILE, &model, conns2.dest_y, conns2.dest_x)) {
|
||||||
struct swchain_conns conns3;
|
struct swchain_conns conns3;
|
||||||
|
struct sw_chain chain3;
|
||||||
|
|
||||||
printf("conn2 chain_size %i connpt_o %i num_dests %i i %i y %i x %i str %s\n",
|
printf("conn2 chain_size %i connpt_o %i num_dests %i i %i y %i x %i str %s\n",
|
||||||
conns2.chain.chain_size, conns2.connpt_dest_start,
|
conns2.chain.chain_size, conns2.connpt_dest_start,
|
||||||
conns2.num_dests, conns2.dest_i, conns2.dest_y, conns2.dest_x, conns2.dest_str);
|
conns2.num_dests, conns2.dest_i, conns2.dest_y, conns2.dest_x, conns2.dest_str);
|
||||||
|
|
||||||
#if 0
|
|
||||||
rc = printf_switchtree(&model, conns2.dest_y,
|
|
||||||
conns2.dest_x, conns2.dest_str, /*indent*/ 3);
|
|
||||||
if (rc) FAIL(rc);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
strcpy(tmp_str, conns2.dest_str);
|
strcpy(tmp_str, conns2.dest_str);
|
||||||
|
printf_swconns(&model, conns2.dest_y, conns2.dest_x, tmp_str);
|
||||||
|
|
||||||
conns3.model = &model;
|
conns3.model = &model;
|
||||||
conns3.y = conns2.dest_y;
|
conns3.y = conns2.dest_y;
|
||||||
conns3.x = conns2.dest_x;
|
conns3.x = conns2.dest_x;
|
||||||
conns3.start_switch = tmp_str;
|
conns3.start_switch = tmp_str;
|
||||||
while (fpga_switch_conns_enum(&conns3) != NO_CONN) {
|
while (fpga_switch_conns_enum(&conns3) != NO_CONN) {
|
||||||
printf("conn3 chain_size %i connpt_o %i num_dests %i i %i y %i x %i str %s\n",
|
if (is_atyx(YX_ROUTING_TO_FABLOGIC, &model, conns3.dest_y, conns3.dest_x)) {
|
||||||
conns3.chain.chain_size, conns3.connpt_dest_start,
|
printf("route to y%02i x%02i\n", conns3.dest_y, conns3.dest_x);
|
||||||
conns3.num_dests, conns3.dest_i, conns3.dest_y, conns3.dest_x, conns3.dest_str);
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
rc = printf_switchtree(&model, conns.dest_y,
|
|
||||||
conns.dest_x, conns.dest_str, /*indent*/ 3);
|
|
||||||
if (rc) FAIL(rc);
|
|
||||||
|
|
||||||
// go through whole tree of what is reachable from that
|
|
||||||
// switch, look for outside connections that reach to a routing tile
|
|
||||||
chain.model = &model;
|
|
||||||
chain.y = conns.dest_y;
|
|
||||||
chain.x = conns.dest_x;
|
|
||||||
chain.start_switch = conns.dest_str;
|
|
||||||
chain.from_to = SW_FROM;
|
|
||||||
while (fpga_switch_chain_enum(&chain) != NO_SWITCH) {
|
|
||||||
printf("idx %i chain_size %i from %s to %s\n",
|
|
||||||
chain.chain[chain.chain_size-1], chain.chain_size-1,
|
|
||||||
fpga_switch_str(&model, chain.y, chain.x, chain.chain[chain.chain_size-1], SW_FROM),
|
|
||||||
fpga_switch_str(&model, chain.y, chain.x, chain.chain[chain.chain_size-1], SW_TO));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
printf("P48 O pinw %s\n", P48_dev->iob.pinw_in_O);
|
printf("P48 O pinw %s\n", P48_dev->iob.pinw_in_O);
|
||||||
|
|
||||||
|
|
107
control.c
107
control.c
|
@ -333,9 +333,7 @@ swidx_t fpga_switch_first(struct fpga_model* model, int y, int x,
|
||||||
// Finds the first switch either from or to the name given.
|
// Finds the first switch either from or to the name given.
|
||||||
tile = YX_TILE(model, y, x);
|
tile = YX_TILE(model, y, x);
|
||||||
for (i = 0; i < tile->num_switches; i++) {
|
for (i = 0; i < tile->num_switches; i++) {
|
||||||
connpt_o = (from_to == SW_FROM)
|
connpt_o = SW_I(tile->switches[i], from_to);
|
||||||
? SWITCH_FROM(tile->switches[i])
|
|
||||||
: SWITCH_TO(tile->switches[i]);
|
|
||||||
if (tile->conn_point_names[connpt_o*2+1] == name_i)
|
if (tile->conn_point_names[connpt_o*2+1] == name_i)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -351,15 +349,11 @@ static swidx_t fpga_switch_search(struct fpga_model* model, int y, int x,
|
||||||
int connpt_o, name_i, i;
|
int connpt_o, name_i, i;
|
||||||
|
|
||||||
tile = YX_TILE(model, y, x);
|
tile = YX_TILE(model, y, x);
|
||||||
connpt_o = (from_to == SW_FROM)
|
connpt_o = SW_I(tile->switches[last], from_to);
|
||||||
? SWITCH_FROM(tile->switches[last])
|
|
||||||
: SWITCH_TO(tile->switches[last]);
|
|
||||||
name_i = tile->conn_point_names[connpt_o*2+1];
|
name_i = tile->conn_point_names[connpt_o*2+1];
|
||||||
|
|
||||||
for (i = search_beg; i < tile->num_switches; i++) {
|
for (i = search_beg; i < tile->num_switches; i++) {
|
||||||
connpt_o = (from_to == SW_FROM)
|
connpt_o = SW_I(tile->switches[i], from_to);
|
||||||
? SWITCH_FROM(tile->switches[i])
|
|
||||||
: SWITCH_TO(tile->switches[i]);
|
|
||||||
if (tile->conn_point_names[connpt_o*2+1] == name_i)
|
if (tile->conn_point_names[connpt_o*2+1] == name_i)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +372,7 @@ 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);
|
return fpga_switch_search(model, y, x, last, /*search_beg*/ 0, from_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUM_CONNPT_BUFS 16
|
#define NUM_CONNPT_BUFS 64
|
||||||
#define CONNPT_BUF_SIZE 128
|
#define CONNPT_BUF_SIZE 128
|
||||||
|
|
||||||
static const char* connpt_str(struct fpga_model* model, int y, int x, int connpt_o)
|
static const char* connpt_str(struct fpga_model* model, int y, int x, int connpt_o)
|
||||||
|
@ -406,8 +400,7 @@ const char* fpga_switch_str(struct fpga_model* model, int y, int x,
|
||||||
swidx_t swidx, int from_to)
|
swidx_t swidx, int from_to)
|
||||||
{
|
{
|
||||||
uint32_t sw = YX_TILE(model, y, x)->switches[swidx];
|
uint32_t sw = YX_TILE(model, y, x)->switches[swidx];
|
||||||
return connpt_str(model, y, x,
|
return connpt_str(model, y, x, SW_I(sw, from_to));
|
||||||
(from_to == SW_FROM) ? SWITCH_FROM(sw) : SWITCH_TO(sw));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int fpga_switch_is_bidir(struct fpga_model* model, int y, int x,
|
int fpga_switch_is_bidir(struct fpga_model* model, int y, int x,
|
||||||
|
@ -434,9 +427,64 @@ void fpga_switch_disable(struct fpga_model* model, int y, int x,
|
||||||
YX_TILE(model, y, x)->switches[swidx] &= ~SWITCH_ON;
|
YX_TILE(model, y, x)->switches[swidx] &= ~SWITCH_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SW_BUF_SIZE 256
|
||||||
|
#define NUM_SW_BUFS 64
|
||||||
|
|
||||||
|
const char* fmt_sw(struct fpga_model* model, int y, int x, swidx_t sw, int from_to)
|
||||||
|
{
|
||||||
|
static char sw_buf[NUM_SW_BUFS][SW_BUF_SIZE];
|
||||||
|
static int last_buf = 0;
|
||||||
|
char midstr[64];
|
||||||
|
|
||||||
|
last_buf = (last_buf+1)%NUM_SW_BUFS;
|
||||||
|
|
||||||
|
strcpy(midstr, fpga_switch_is_enabled(model, y, x, sw) ? "on:" : "");
|
||||||
|
if (fpga_switch_is_bidir(model, y, x, sw))
|
||||||
|
strcat(midstr, "<->");
|
||||||
|
else {
|
||||||
|
// a 'to-switch' is actually still a switch that physically
|
||||||
|
// points in the other direction (unless it's a bidir switch),
|
||||||
|
// so when displaying the 'to-switch', we make the arrow point
|
||||||
|
// to the left side to match the physical direction.
|
||||||
|
strcat(midstr, (from_to == SW_TO) ? "<-" : "->");
|
||||||
|
}
|
||||||
|
// fmt_sw() prints only the destination side of the switch (!from_to),
|
||||||
|
// because it is the significant one in a chain of switches, and if the
|
||||||
|
// caller wants the source side they can add it outside.
|
||||||
|
snprintf(sw_buf[last_buf], sizeof(sw_buf[0]), "%s%s%s",
|
||||||
|
(from_to == SW_FROM) ? "" : fpga_switch_str(model, y, x, sw, SW_FROM),
|
||||||
|
midstr,
|
||||||
|
(from_to == SW_TO) ? "" : fpga_switch_str(model, y, x, sw, SW_TO));
|
||||||
|
|
||||||
|
return sw_buf[last_buf];
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FMT_SWCHAIN_BUF_SIZE 2048
|
||||||
|
#define FMT_SWCHAIN_NUM_BUFS 8
|
||||||
|
|
||||||
|
const char* fmt_swchain(struct fpga_model* model, int y, int x,
|
||||||
|
swidx_t* sw, int sw_size)
|
||||||
|
{
|
||||||
|
static char buf[FMT_SWCHAIN_NUM_BUFS][FMT_SWCHAIN_BUF_SIZE];
|
||||||
|
static int last_buf = 0;
|
||||||
|
int i, o;
|
||||||
|
|
||||||
|
last_buf = (last_buf+1)%FMT_SWCHAIN_NUM_BUFS;
|
||||||
|
o = 0;
|
||||||
|
for (i = 0; i < sw_size; i++) {
|
||||||
|
if (i) buf[last_buf][o++] = ' ';
|
||||||
|
strcpy(&buf[last_buf][o], fmt_sw(model, y, x, sw[i], SW_FROM));
|
||||||
|
o += strlen(&buf[last_buf][o]);
|
||||||
|
}
|
||||||
|
buf[last_buf][o] = 0;
|
||||||
|
return buf[last_buf];
|
||||||
|
}
|
||||||
|
|
||||||
int fpga_switch_chain_enum(struct sw_chain* chain)
|
int fpga_switch_chain_enum(struct sw_chain* chain)
|
||||||
{
|
{
|
||||||
swidx_t idx;
|
swidx_t idx;
|
||||||
|
struct fpga_tile* tile;
|
||||||
|
int child_from_to, i;
|
||||||
|
|
||||||
if (chain->start_switch != SW_CHAIN_NEXT) {
|
if (chain->start_switch != SW_CHAIN_NEXT) {
|
||||||
idx = fpga_switch_first(chain->model, chain->y, chain->x,
|
idx = fpga_switch_first(chain->model, chain->y, chain->x,
|
||||||
|
@ -478,24 +526,39 @@ int fpga_switch_chain_enum(struct sw_chain* chain)
|
||||||
chain->chain[chain->chain_size-1] = idx;
|
chain->chain[chain->chain_size-1] = idx;
|
||||||
}
|
}
|
||||||
// look for children
|
// look for children
|
||||||
|
tile = YX_TILE(chain->model, chain->y, chain->x);
|
||||||
while (1) {
|
while (1) {
|
||||||
idx = fpga_switch_first(chain->model, chain->y, chain->x,
|
idx = fpga_switch_first(chain->model, chain->y, chain->x,
|
||||||
fpga_switch_str(chain->model, chain->y, chain->x,
|
fpga_switch_str(chain->model, chain->y, chain->x,
|
||||||
chain->chain[chain->chain_size-1], !chain->from_to),
|
chain->chain[chain->chain_size-1], !chain->from_to),
|
||||||
chain->from_to);
|
chain->from_to);
|
||||||
chain->chain[chain->chain_size-1] = fpga_switch_next(
|
child_from_to = SW_I(tile->switches[chain->chain[chain->chain_size-1]],
|
||||||
chain->model, chain->y, chain->x,
|
!chain->from_to);
|
||||||
chain->chain[chain->chain_size-1], chain->from_to);
|
|
||||||
if (idx != NO_SWITCH) {
|
if (idx != NO_SWITCH) {
|
||||||
if (chain->chain_size >= MAX_SW_CHAIN_SIZE) {
|
// If we have the same from-switch already among the
|
||||||
HERE(); goto internal_error;
|
// parents, don't fall into endless recursion...
|
||||||
|
for (i = 0; i < chain->chain_size; i++) {
|
||||||
|
if (SW_I(tile->switches[chain->chain[i]], chain->from_to)
|
||||||
|
== child_from_to)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i >= chain->chain_size) {
|
||||||
|
if (chain->chain_size >= MAX_SW_CHAIN_SIZE) {
|
||||||
|
HERE(); goto internal_error;
|
||||||
|
}
|
||||||
|
// back to first round at new level
|
||||||
|
chain->first_round = 1;
|
||||||
|
chain->chain[chain->chain_size] = idx;
|
||||||
|
chain->chain_size++;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
chain->first_round = 1; // back to first round at new level
|
|
||||||
chain->chain[chain->chain_size] = idx;
|
|
||||||
chain->chain_size++;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
while (chain->chain[chain->chain_size-1] == NO_SWITCH) {
|
while (1) {
|
||||||
|
chain->chain[chain->chain_size-1] = fpga_switch_next(
|
||||||
|
chain->model, chain->y, chain->x,
|
||||||
|
chain->chain[chain->chain_size-1], chain->from_to);
|
||||||
|
if (chain->chain[chain->chain_size-1] != NO_SWITCH)
|
||||||
|
break;
|
||||||
if (chain->chain_size <= 1) {
|
if (chain->chain_size <= 1) {
|
||||||
chain->chain_size = 0;
|
chain->chain_size = 0;
|
||||||
return NO_SWITCH;
|
return NO_SWITCH;
|
||||||
|
|
13
control.h
13
control.h
|
@ -40,11 +40,7 @@ int fpga_connpt_lookup(struct fpga_model* model, int y, int x,
|
||||||
const char* fpga_conn_dest(struct fpga_model* model, int y, int x,
|
const char* fpga_conn_dest(struct fpga_model* model, int y, int x,
|
||||||
int connpt_dest_idx, int* dest_y, int* dest_x);
|
int connpt_dest_idx, int* dest_y, int* dest_x);
|
||||||
|
|
||||||
typedef int swidx_t;
|
typedef int swidx_t; // swidx_t is an index into the uint32_t switches array
|
||||||
|
|
||||||
// SW_FROM and SW_TO values are chosen such that ! inverts them.
|
|
||||||
#define SW_FROM 0
|
|
||||||
#define SW_TO 1
|
|
||||||
|
|
||||||
// returns a switch index, or -1 (NO_SWITCH) if no switch was found
|
// 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,
|
swidx_t fpga_switch_first(struct fpga_model* model, int y, int x,
|
||||||
|
@ -65,8 +61,13 @@ void fpga_switch_enable(struct fpga_model* model, int y, int x,
|
||||||
void fpga_switch_disable(struct fpga_model* model, int y, int x,
|
void fpga_switch_disable(struct fpga_model* model, int y, int x,
|
||||||
swidx_t swidx);
|
swidx_t swidx);
|
||||||
|
|
||||||
|
const char* fmt_sw(struct fpga_model* model, int y, int x,
|
||||||
|
swidx_t sw, int from_to);
|
||||||
|
const char* fmt_swchain(struct fpga_model* model, int y, int x,
|
||||||
|
swidx_t* sw, int sw_size);
|
||||||
|
|
||||||
#define SW_CHAIN_NEXT 0 // use for name
|
#define SW_CHAIN_NEXT 0 // use for name
|
||||||
#define MAX_SW_CHAIN_SIZE 32
|
#define MAX_SW_CHAIN_SIZE 32 // largest seen so far was 10
|
||||||
|
|
||||||
struct sw_chain
|
struct sw_chain
|
||||||
{
|
{
|
||||||
|
|
2
helper.h
2
helper.h
|
@ -115,6 +115,8 @@ struct hashed_strarray
|
||||||
#define STRIDX_64K 0xFFFF
|
#define STRIDX_64K 0xFFFF
|
||||||
#define STRIDX_1M 1000000
|
#define STRIDX_1M 1000000
|
||||||
|
|
||||||
|
typedef uint16_t str16_t;
|
||||||
|
|
||||||
int strarray_init(struct hashed_strarray* array, int highest_index);
|
int strarray_init(struct hashed_strarray* array, int highest_index);
|
||||||
void strarray_free(struct hashed_strarray* array);
|
void strarray_free(struct hashed_strarray* array);
|
||||||
|
|
||||||
|
|
37
model.h
37
model.h
|
@ -270,6 +270,10 @@ int is_atx(int check, struct fpga_model* model, int x);
|
||||||
// True for all tiles that are in the regular 0..15 row tiles of a routing col
|
// True for all tiles that are in the regular 0..15 row tiles of a routing col
|
||||||
#define YX_ROUTING_TILE 0x0001
|
#define YX_ROUTING_TILE 0x0001
|
||||||
#define YX_IO_ROUTING 0x0002
|
#define YX_IO_ROUTING 0x0002
|
||||||
|
#define YX_ROUTING_TO_FABLOGIC 0x0004 // left of a regular fabric logic device
|
||||||
|
#define YX_DEV_ILOGIC 0x0008
|
||||||
|
#define YX_DEV_OLOGIC 0x0010
|
||||||
|
#define YX_DEV_LOGIC 0x0020
|
||||||
|
|
||||||
int is_atyx(int check, struct fpga_model* model, int y, int x);
|
int is_atyx(int check, struct fpga_model* model, int y, int x);
|
||||||
|
|
||||||
|
@ -387,8 +391,14 @@ struct fpga_device
|
||||||
#define SWITCH_ON 0x80000000
|
#define SWITCH_ON 0x80000000
|
||||||
#define SWITCH_BIDIRECTIONAL 0x40000000
|
#define SWITCH_BIDIRECTIONAL 0x40000000
|
||||||
#define SWITCH_MAX_CONNPT_O 0x7FFF // 15 bits
|
#define SWITCH_MAX_CONNPT_O 0x7FFF // 15 bits
|
||||||
#define SWITCH_FROM(u32) (((u32) >> 15) & SWITCH_MAX_CONNPT_O)
|
#define SW_FROM_I(u32) (((u32) >> 15) & SWITCH_MAX_CONNPT_O)
|
||||||
#define SWITCH_TO(u32) ((u32) & SWITCH_MAX_CONNPT_O)
|
#define SW_TO_I(u32) ((u32) & SWITCH_MAX_CONNPT_O)
|
||||||
|
|
||||||
|
#define SW_I(u32, from_to) ((from_to) ? SW_FROM_I(u32) : SW_TO_I(u32))
|
||||||
|
// SW_FROM and SW_TO values are chosen such that ! inverts them,
|
||||||
|
// and swf() assumes that SW_FROM is positive.
|
||||||
|
#define SW_FROM 1
|
||||||
|
#define SW_TO 0
|
||||||
|
|
||||||
#define NO_SWITCH -1
|
#define NO_SWITCH -1
|
||||||
#define NO_CONN -1
|
#define NO_CONN -1
|
||||||
|
@ -435,23 +445,30 @@ void fpga_free_model(struct fpga_model* model);
|
||||||
const char* fpga_tiletype_str(enum fpga_tile_type type);
|
const char* fpga_tiletype_str(enum fpga_tile_type type);
|
||||||
|
|
||||||
int init_tiles(struct fpga_model* model);
|
int init_tiles(struct fpga_model* model);
|
||||||
int init_conns(struct fpga_model* model);
|
|
||||||
int init_ports(struct fpga_model* model);
|
|
||||||
int init_devices(struct fpga_model* model);
|
int init_devices(struct fpga_model* model);
|
||||||
void free_devices(struct fpga_model* model);
|
void free_devices(struct fpga_model* model);
|
||||||
int init_switches(struct fpga_model* model);
|
int init_ports(struct fpga_model* model, int dup_warn);
|
||||||
|
int init_conns(struct fpga_model* model);
|
||||||
|
|
||||||
|
int init_switches(struct fpga_model* model, int routing_sw);
|
||||||
|
// replicate_routing_switches() is a high-speed optimized way to
|
||||||
|
// initialize the routing switches, will only work before ports,
|
||||||
|
// connections or other switches.
|
||||||
|
int replicate_routing_switches(struct fpga_model* model);
|
||||||
|
|
||||||
const char* pf(const char* fmt, ...);
|
const char* pf(const char* fmt, ...);
|
||||||
const char* wpref(struct fpga_model* model, int y, int x, const char* wire_name);
|
const char* wpref(struct fpga_model* model, int y, int x, const char* wire_name);
|
||||||
char next_non_whitespace(const char* s);
|
char next_non_whitespace(const char* s);
|
||||||
char last_major(const char* str, int cur_o);
|
char last_major(const char* str, int cur_o);
|
||||||
int has_connpt(struct fpga_model* model, int y, int x, const char* name);
|
int has_connpt(struct fpga_model* model, int y, int x, const char* name);
|
||||||
int add_connpt_name(struct fpga_model* model, int y, int x, const char* connpt_name);
|
int add_connpt_name(struct fpga_model* model, int y, int x,
|
||||||
|
const char* connpt_name, int dup_warn);
|
||||||
|
|
||||||
int has_device(struct fpga_model* model, int y, int x, int dev);
|
int has_device(struct fpga_model* model, int y, int x, int dev);
|
||||||
int has_device_type(struct fpga_model* model, int y, int x, int dev, int subtype);
|
int has_device_type(struct fpga_model* model, int y, int x, int dev, int subtype);
|
||||||
int add_connpt_2(struct fpga_model* model, int y, int x,
|
int add_connpt_2(struct fpga_model* model, int y, int x,
|
||||||
const char* connpt_name, const char* suffix1, const char* suffix2);
|
const char* connpt_name, const char* suffix1, const char* suffix2,
|
||||||
|
int dup_warn);
|
||||||
|
|
||||||
typedef int (*add_conn_f)(struct fpga_model* model,
|
typedef int (*add_conn_f)(struct fpga_model* model,
|
||||||
int y1, int x1, const char* name1,
|
int y1, int x1, const char* name1,
|
||||||
|
@ -508,6 +525,12 @@ int add_switch(struct fpga_model* model, int y, int x, const char* from,
|
||||||
int add_switch_set(struct fpga_model* model, int y, int x, const char* prefix,
|
int add_switch_set(struct fpga_model* model, int y, int x, const char* prefix,
|
||||||
const char** pairs, int suffix_inc);
|
const char** pairs, int suffix_inc);
|
||||||
|
|
||||||
|
// This will replicate the entire conn_point_names and switches arrays
|
||||||
|
// from one tile to another, assuming that all of conn_point_names,
|
||||||
|
// switches and conn_point_dests in the destination tile are empty.
|
||||||
|
int replicate_switches_and_names(struct fpga_model* model,
|
||||||
|
int y_from, int x_from, int y_to, int x_to);
|
||||||
|
|
||||||
struct seed_data
|
struct seed_data
|
||||||
{
|
{
|
||||||
int x_flags;
|
int x_flags;
|
||||||
|
|
|
@ -788,11 +788,11 @@ static int run_io_wires(struct fpga_model* model)
|
||||||
for (i = 0; s[i][0]; i++) {
|
for (i = 0; s[i][0]; i++) {
|
||||||
struct w_net net1 = {
|
struct w_net net1 = {
|
||||||
1,
|
1,
|
||||||
{{ pf("BIOB_%s%%i", s[i]), 0, y, x },
|
{{ pf("BIOI_INNER_%s%%i", s[i]), 0, y-3, x+1 },
|
||||||
{ pf("IOI_BTERM_IOIUP_%s%%i", s[i]), 0, y-1, x },
|
|
||||||
{ pf("BTERM_IOIUP_%s%%i", s[i]), 0, y-1, x+1 },
|
|
||||||
{ pf("BIOI_OUTER_%s%%i_EXT", s[i]), 0, y-2, x+1 },
|
{ pf("BIOI_OUTER_%s%%i_EXT", s[i]), 0, y-2, x+1 },
|
||||||
{ pf("BIOI_INNER_%s%%i", s[i]), 0, y-3, x+1 },
|
{ pf("BTERM_IOIUP_%s%%i", s[i]), 0, y-1, x+1 },
|
||||||
|
{ pf("IOI_BTERM_IOIUP_%s%%i", s[i]), 0, y-1, x },
|
||||||
|
{ pf("BIOB_%s%%i", s[i]), 0, y, x },
|
||||||
{ "" }}};
|
{ "" }}};
|
||||||
|
|
||||||
if ((rc = add_conn_net(model, NOPREF_BI_F, &net1))) goto xout;
|
if ((rc = add_conn_net(model, NOPREF_BI_F, &net1))) goto xout;
|
||||||
|
|
|
@ -57,37 +57,37 @@ static int init_iob(struct fpga_model* model, int y, int x,
|
||||||
snprintf(tile->devs[idx].iob.pinw_in_O,
|
snprintf(tile->devs[idx].iob.pinw_in_O,
|
||||||
sizeof(tile->devs[idx].iob.pinw_in_O),
|
sizeof(tile->devs[idx].iob.pinw_in_O),
|
||||||
"%s_O%i_PINW", prefix, type_idx);
|
"%s_O%i_PINW", prefix, type_idx);
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_O);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_O, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
snprintf(tile->devs[idx].iob.pinw_in_T,
|
snprintf(tile->devs[idx].iob.pinw_in_T,
|
||||||
sizeof(tile->devs[idx].iob.pinw_in_T),
|
sizeof(tile->devs[idx].iob.pinw_in_T),
|
||||||
"%s_T%i_PINW", prefix, type_idx);
|
"%s_T%i_PINW", prefix, type_idx);
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_T);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_T, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
snprintf(tile->devs[idx].iob.pinw_out_I,
|
snprintf(tile->devs[idx].iob.pinw_out_I,
|
||||||
sizeof(tile->devs[idx].iob.pinw_out_I),
|
sizeof(tile->devs[idx].iob.pinw_out_I),
|
||||||
"%s_IBUF%i_PINW", prefix, type_idx);
|
"%s_IBUF%i_PINW", prefix, type_idx);
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_I);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_I, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
snprintf(tile->devs[idx].iob.pinw_out_PADOUT,
|
snprintf(tile->devs[idx].iob.pinw_out_PADOUT,
|
||||||
sizeof(tile->devs[idx].iob.pinw_out_PADOUT),
|
sizeof(tile->devs[idx].iob.pinw_out_PADOUT),
|
||||||
"%s_PADOUT%i", prefix, type_idx);
|
"%s_PADOUT%i", prefix, type_idx);
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_PADOUT);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_PADOUT, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
snprintf(tile->devs[idx].iob.pinw_in_DIFFI_IN,
|
snprintf(tile->devs[idx].iob.pinw_in_DIFFI_IN,
|
||||||
sizeof(tile->devs[idx].iob.pinw_in_DIFFI_IN),
|
sizeof(tile->devs[idx].iob.pinw_in_DIFFI_IN),
|
||||||
"%s_DIFFI_IN%i", prefix, type_idx);
|
"%s_DIFFI_IN%i", prefix, type_idx);
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_DIFFI_IN);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_DIFFI_IN, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
snprintf(tile->devs[idx].iob.pinw_in_DIFFO_IN,
|
snprintf(tile->devs[idx].iob.pinw_in_DIFFO_IN,
|
||||||
sizeof(tile->devs[idx].iob.pinw_in_DIFFO_IN),
|
sizeof(tile->devs[idx].iob.pinw_in_DIFFO_IN),
|
||||||
"%s_DIFFO_IN%i", prefix, type_idx);
|
"%s_DIFFO_IN%i", prefix, type_idx);
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_DIFFO_IN);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_DIFFO_IN, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
snprintf(tile->devs[idx].iob.pinw_out_DIFFO_OUT,
|
snprintf(tile->devs[idx].iob.pinw_out_DIFFO_OUT,
|
||||||
sizeof(tile->devs[idx].iob.pinw_out_DIFFO_OUT),
|
sizeof(tile->devs[idx].iob.pinw_out_DIFFO_OUT),
|
||||||
"%s_DIFFO_OUT%i", prefix, type_idx);
|
"%s_DIFFO_OUT%i", prefix, type_idx);
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_DIFFO_OUT);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_DIFFO_OUT, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
if (!x && y == model->center_y - CENTER_TOP_IOB_O && type_idx == 1)
|
if (!x && y == model->center_y - CENTER_TOP_IOB_O && type_idx == 1)
|
||||||
|
@ -103,7 +103,7 @@ static int init_iob(struct fpga_model* model, int y, int x,
|
||||||
sizeof(tile->devs[idx].iob.pinw_out_PCI_RDY),
|
sizeof(tile->devs[idx].iob.pinw_out_PCI_RDY),
|
||||||
"%s_PCI_RDY%i", prefix, type_idx);
|
"%s_PCI_RDY%i", prefix, type_idx);
|
||||||
}
|
}
|
||||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_PCI_RDY);
|
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_PCI_RDY, /*dup_warn*/ 1);
|
||||||
if (rc) FAIL(rc);
|
if (rc) FAIL(rc);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
|
|
116
model_helper.c
116
model_helper.c
|
@ -76,15 +76,29 @@ static int _add_connpt_name(struct fpga_model* model, int y, int x,
|
||||||
int* conn_point_o);
|
int* conn_point_o);
|
||||||
|
|
||||||
int add_connpt_name(struct fpga_model* model, int y, int x,
|
int add_connpt_name(struct fpga_model* model, int y, int x,
|
||||||
const char* connpt_name)
|
const char* connpt_name, int dup_warn)
|
||||||
{
|
{
|
||||||
return _add_connpt_name(model, y, x, connpt_name,
|
return _add_connpt_name(model, y, x, connpt_name, dup_warn,
|
||||||
1 /* warn_if_duplicate */,
|
|
||||||
0 /* name_i */, 0 /* conn_point_o */);
|
0 /* name_i */, 0 /* conn_point_o */);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONN_NAMES_INCREMENT 128
|
#define CONN_NAMES_INCREMENT 128
|
||||||
|
|
||||||
|
// add_switch() assumes that the new element is appended
|
||||||
|
// at the end of the array.
|
||||||
|
static void connpt_names_array_append(struct fpga_tile* tile, int name_i)
|
||||||
|
{
|
||||||
|
if (!(tile->num_conn_point_names % CONN_NAMES_INCREMENT)) {
|
||||||
|
uint16_t* new_ptr = realloc(tile->conn_point_names,
|
||||||
|
(tile->num_conn_point_names+CONN_NAMES_INCREMENT)*2*sizeof(uint16_t));
|
||||||
|
if (!new_ptr) EXIT(ENOMEM);
|
||||||
|
tile->conn_point_names = new_ptr;
|
||||||
|
}
|
||||||
|
tile->conn_point_names[tile->num_conn_point_names*2] = tile->num_conn_point_dests;
|
||||||
|
tile->conn_point_names[tile->num_conn_point_names*2+1] = name_i;
|
||||||
|
tile->num_conn_point_names++;
|
||||||
|
}
|
||||||
|
|
||||||
static int _add_connpt_name(struct fpga_model* model, int y, int x,
|
static int _add_connpt_name(struct fpga_model* model, int y, int x,
|
||||||
const char* connpt_name, int warn_if_duplicate, uint16_t* name_i,
|
const char* connpt_name, int warn_if_duplicate, uint16_t* name_i,
|
||||||
int* conn_point_o)
|
int* conn_point_o)
|
||||||
|
@ -117,18 +131,7 @@ static int _add_connpt_name(struct fpga_model* model, int y, int x,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// This is the first connection under name, add name.
|
// This is the first connection under name, add name.
|
||||||
if (!(tile->num_conn_point_names % CONN_NAMES_INCREMENT)) {
|
connpt_names_array_append(tile, _name_i);
|
||||||
uint16_t* new_ptr = realloc(tile->conn_point_names,
|
|
||||||
(tile->num_conn_point_names+CONN_NAMES_INCREMENT)*2*sizeof(uint16_t));
|
|
||||||
if (!new_ptr) {
|
|
||||||
fprintf(stderr, "Out of memory %s:%i\n", __FILE__, __LINE__);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
tile->conn_point_names = new_ptr;
|
|
||||||
}
|
|
||||||
tile->conn_point_names[tile->num_conn_point_names*2] = tile->num_conn_point_dests;
|
|
||||||
tile->conn_point_names[tile->num_conn_point_names*2+1] = _name_i;
|
|
||||||
tile->num_conn_point_names++;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,16 +171,17 @@ int has_device_type(struct fpga_model* model, int y, int x, int dev, int subtype
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_connpt_2(struct fpga_model* model, int y, int x,
|
int add_connpt_2(struct fpga_model* model, int y, int x,
|
||||||
const char* connpt_name, const char* suffix1, const char* suffix2)
|
const char* connpt_name, const char* suffix1, const char* suffix2,
|
||||||
|
int dup_warn)
|
||||||
{
|
{
|
||||||
char name_buf[64];
|
char name_buf[64];
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
snprintf(name_buf, sizeof(name_buf), "%s%s", connpt_name, suffix1);
|
snprintf(name_buf, sizeof(name_buf), "%s%s", connpt_name, suffix1);
|
||||||
rc = add_connpt_name(model, y, x, name_buf);
|
rc = add_connpt_name(model, y, x, name_buf, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
snprintf(name_buf, sizeof(name_buf), "%s%s", connpt_name, suffix2);
|
snprintf(name_buf, sizeof(name_buf), "%s%s", connpt_name, suffix2);
|
||||||
rc = add_connpt_name(model, y, x, name_buf);
|
rc = add_connpt_name(model, y, x, name_buf, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
return 0;
|
return 0;
|
||||||
xout:
|
xout:
|
||||||
|
@ -322,9 +326,13 @@ xout:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SWITCH_ALLOC_INCREMENT 64
|
#define SWITCH_ALLOC_INCREMENT 256
|
||||||
|
|
||||||
#define DBG_ALLOW_ADDPOINTS
|
#define DBG_ALLOW_ADDPOINTS
|
||||||
|
// Enable CHECK_DUPLICATES when working on the switch architecture,
|
||||||
|
// but otherwise keep it disabled since it slows down building the
|
||||||
|
// model a lot.
|
||||||
|
#undef CHECK_DUPLICATES
|
||||||
|
|
||||||
int add_switch(struct fpga_model* model, int y, int x, const char* from,
|
int add_switch(struct fpga_model* model, int y, int x, const char* from,
|
||||||
const char* to, int is_bidirectional)
|
const char* to, int is_bidirectional)
|
||||||
|
@ -352,42 +360,31 @@ int add_switch(struct fpga_model* model, int y, int x, const char* from,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It seems searching backwards is a little faster than
|
||||||
|
// searching forwards. Merging the two loops into one
|
||||||
|
// made the total slower, presumably due to cache issues.
|
||||||
from_connpt_o = -1;
|
from_connpt_o = -1;
|
||||||
for (i = 0; i < tile->num_conn_point_names; i++) {
|
for (i = tile->num_conn_point_names-1; i >= 0; i--) {
|
||||||
if (tile->conn_point_names[i*2+1] == from_idx) {
|
if (tile->conn_point_names[i*2+1] == from_idx) {
|
||||||
from_connpt_o = i;
|
from_connpt_o = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DBG_ALLOW_ADDPOINTS
|
|
||||||
if (from_connpt_o == -1) {
|
|
||||||
rc = add_connpt_name(model, y, x, from);
|
|
||||||
if (rc) goto xout;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
to_connpt_o = -1;
|
to_connpt_o = -1;
|
||||||
for (i = 0; i < tile->num_conn_point_names; i++) {
|
for (i = tile->num_conn_point_names-1; i >= 0; i--) {
|
||||||
if (tile->conn_point_names[i*2+1] == to_idx) {
|
if (tile->conn_point_names[i*2+1] == to_idx) {
|
||||||
to_connpt_o = i;
|
to_connpt_o = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DBG_ALLOW_ADDPOINTS
|
#ifdef DBG_ALLOW_ADDPOINTS
|
||||||
|
if (from_connpt_o == -1) {
|
||||||
|
from_connpt_o = tile->num_conn_point_names;
|
||||||
|
connpt_names_array_append(tile, from_idx);
|
||||||
|
}
|
||||||
if (to_connpt_o == -1) {
|
if (to_connpt_o == -1) {
|
||||||
rc = add_connpt_name(model, y, x, to);
|
to_connpt_o = tile->num_conn_point_names;
|
||||||
if (rc) goto xout;
|
connpt_names_array_append(tile, to_idx);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (from_connpt_o == -1 || to_connpt_o == -1) {
|
if (from_connpt_o == -1 || to_connpt_o == -1) {
|
||||||
|
@ -405,6 +402,7 @@ int add_switch(struct fpga_model* model, int y, int x, const char* from,
|
||||||
if (is_bidirectional)
|
if (is_bidirectional)
|
||||||
new_switch |= SWITCH_BIDIRECTIONAL;
|
new_switch |= SWITCH_BIDIRECTIONAL;
|
||||||
|
|
||||||
|
#ifdef CHECK_DUPLICATES
|
||||||
for (i = 0; i < tile->num_switches; i++) {
|
for (i = 0; i < tile->num_switches; i++) {
|
||||||
if ((tile->switches[i] & 0x3FFFFFFF) == (new_switch & 0x3FFFFFFF)) {
|
if ((tile->switches[i] & 0x3FFFFFFF) == (new_switch & 0x3FFFFFFF)) {
|
||||||
fprintf(stderr, "Internal error in %s:%i duplicate switch from %s to %s\n",
|
fprintf(stderr, "Internal error in %s:%i duplicate switch from %s to %s\n",
|
||||||
|
@ -412,6 +410,7 @@ int add_switch(struct fpga_model* model, int y, int x, const char* from,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (!(tile->num_switches % SWITCH_ALLOC_INCREMENT)) {
|
if (!(tile->num_switches % SWITCH_ALLOC_INCREMENT)) {
|
||||||
uint32_t* new_ptr = realloc(tile->switches,
|
uint32_t* new_ptr = realloc(tile->switches,
|
||||||
(tile->num_switches+SWITCH_ALLOC_INCREMENT)*sizeof(*tile->switches));
|
(tile->num_switches+SWITCH_ALLOC_INCREMENT)*sizeof(*tile->switches));
|
||||||
|
@ -457,6 +456,35 @@ xout:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int replicate_switches_and_names(struct fpga_model* model,
|
||||||
|
int y_from, int x_from, int y_to, int x_to)
|
||||||
|
{
|
||||||
|
struct fpga_tile* from_tile, *to_tile;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
from_tile = YX_TILE(model, y_from, x_from);
|
||||||
|
to_tile = YX_TILE(model, y_to, x_to);
|
||||||
|
if (to_tile->num_conn_point_names
|
||||||
|
|| to_tile->num_conn_point_dests
|
||||||
|
|| to_tile->num_switches
|
||||||
|
|| from_tile->num_conn_point_dests
|
||||||
|
|| !from_tile->num_conn_point_names
|
||||||
|
|| !from_tile->num_switches) FAIL(EINVAL);
|
||||||
|
|
||||||
|
to_tile->conn_point_names = malloc(((from_tile->num_conn_point_names/CONN_NAMES_INCREMENT)+1)*CONN_NAMES_INCREMENT*2*sizeof(uint16_t));
|
||||||
|
if (!to_tile->conn_point_names) EXIT(ENOMEM);
|
||||||
|
memcpy(to_tile->conn_point_names, from_tile->conn_point_names, from_tile->num_conn_point_names*2*sizeof(uint16_t));
|
||||||
|
to_tile->num_conn_point_names = from_tile->num_conn_point_names;
|
||||||
|
|
||||||
|
to_tile->switches = malloc(((from_tile->num_switches/SWITCH_ALLOC_INCREMENT)+1)*SWITCH_ALLOC_INCREMENT*sizeof(*from_tile->switches));
|
||||||
|
if (!to_tile->switches) EXIT(ENOMEM);
|
||||||
|
memcpy(to_tile->switches, from_tile->switches, from_tile->num_switches*sizeof(*from_tile->switches));
|
||||||
|
to_tile->num_switches = from_tile->num_switches;
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
void seed_strx(struct fpga_model* model, struct seed_data* data)
|
void seed_strx(struct fpga_model* model, struct seed_data* data)
|
||||||
{
|
{
|
||||||
int x, i;
|
int x, i;
|
||||||
|
@ -584,6 +612,12 @@ int is_atyx(int check, struct fpga_model* model, int y, int x)
|
||||||
tile = YX_TILE(model, y, x);
|
tile = YX_TILE(model, y, x);
|
||||||
if (check & YX_IO_ROUTING
|
if (check & YX_IO_ROUTING
|
||||||
&& (tile->type == IO_ROUTING || tile->type == ROUTING_IO_L)) return 1;
|
&& (tile->type == IO_ROUTING || tile->type == ROUTING_IO_L)) return 1;
|
||||||
|
if (check & YX_ROUTING_TO_FABLOGIC
|
||||||
|
&& model->tiles[x].flags & TF_FABRIC_ROUTING_COL
|
||||||
|
&& has_device(model, y, x+1, DEV_LOGIC)) return 1;
|
||||||
|
if (check & YX_DEV_ILOGIC && has_device(model, y, x, DEV_ILOGIC)) return 1;
|
||||||
|
if (check & YX_DEV_OLOGIC && has_device(model, y, x, DEV_OLOGIC)) return 1;
|
||||||
|
if (check & YX_DEV_LOGIC && has_device(model, y, x, DEV_LOGIC)) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
model_main.c
29
model_main.c
|
@ -8,8 +8,10 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* columns,
|
static int s_high_speed_replicate = 1;
|
||||||
const char* left_wiring, const char* right_wiring)
|
|
||||||
|
int fpga_build_model(struct fpga_model* model, int fpga_rows,
|
||||||
|
const char* columns, const char* left_wiring, const char* right_wiring)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -27,21 +29,30 @@ int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* column
|
||||||
// that the codes can build upon each other.
|
// that the codes can build upon each other.
|
||||||
|
|
||||||
rc = init_tiles(model);
|
rc = init_tiles(model);
|
||||||
if (rc) return rc;
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
rc = init_devices(model);
|
rc = init_devices(model);
|
||||||
if (rc) return rc;
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
rc = init_ports(model);
|
if (s_high_speed_replicate) {
|
||||||
if (rc) return rc;
|
rc = replicate_routing_switches(model);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: compare.ports only works if other switches and conns
|
||||||
|
// are disabled, as long as not all connections are supported
|
||||||
|
rc = init_ports(model, /*dup_warn*/ !s_high_speed_replicate);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
rc = init_conns(model);
|
rc = init_conns(model);
|
||||||
if (rc) return rc;
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
rc = init_switches(model);
|
rc = init_switches(model, /*routing_sw*/ !s_high_speed_replicate);
|
||||||
if (rc) return rc;
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpga_free_model(struct fpga_model* model)
|
void fpga_free_model(struct fpga_model* model)
|
||||||
|
|
171
model_ports.c
171
model_ports.c
|
@ -13,7 +13,8 @@ enum which_side
|
||||||
TOP_S, BOTTOM_S, RIGHT_S, LEFT_S
|
TOP_S, BOTTOM_S, RIGHT_S, LEFT_S
|
||||||
};
|
};
|
||||||
|
|
||||||
static int init_iologic_ports(struct fpga_model* model, int y, int x, enum which_side side)
|
static int init_iologic_ports(struct fpga_model* model, int y, int x,
|
||||||
|
enum which_side side, int dup_warn)
|
||||||
{
|
{
|
||||||
static const char* prefix, *suffix1, *suffix2;
|
static const char* prefix, *suffix1, *suffix2;
|
||||||
int rc, i;
|
int rc, i;
|
||||||
|
@ -34,53 +35,53 @@ static int init_iologic_ports(struct fpga_model* model, int y, int x, enum which
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = X_A /* 0 */; i <= M_DQ /* 23 */; i++) {
|
for (i = X_A /* 0 */; i <= M_DQ /* 23 */; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("IOI_INTER_LOGICOUT%i", i));
|
rc = add_connpt_name(model, y, x, pf("IOI_INTER_LOGICOUT%i", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_GND_TIEOFF", prefix));
|
rc = add_connpt_name(model, y, x, pf("%s_GND_TIEOFF", prefix), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_VCC_TIEOFF", prefix));
|
rc = add_connpt_name(model, y, x, pf("%s_VCC_TIEOFF", prefix), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_KEEP1_STUB", prefix));
|
rc = add_connpt_name(model, y, x, pf("%s_KEEP1_STUB", prefix), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
for (i = 0; i <= 4; i++) {
|
for (i = 0; i <= 4; i++) {
|
||||||
rc = add_connpt_2(model, y, x, pf("AUXADDR%i_IODELAY", i), suffix1, suffix2);
|
rc = add_connpt_2(model, y, x, pf("AUXADDR%i_IODELAY", i), suffix1, suffix2, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
rc = add_connpt_2(model, y, x, "AUXSDOIN_IODELAY", suffix1, suffix2);
|
rc = add_connpt_2(model, y, x, "AUXSDOIN_IODELAY", suffix1, suffix2, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, "AUXSDO_IODELAY", suffix1, suffix2);
|
rc = add_connpt_2(model, y, x, "AUXSDO_IODELAY", suffix1, suffix2, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, "MEMUPDATE_IODELAY", suffix1, suffix2);
|
rc = add_connpt_2(model, y, x, "MEMUPDATE_IODELAY", suffix1, suffix2, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
rc = add_connpt_name(model, y, x, "OUTN_IODELAY_SITE");
|
rc = add_connpt_name(model, y, x, "OUTN_IODELAY_SITE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "STUB_OUTN_IODELAY_S");
|
rc = add_connpt_name(model, y, x, "STUB_OUTN_IODELAY_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "OUTP_IODELAY_SITE");
|
rc = add_connpt_name(model, y, x, "OUTP_IODELAY_SITE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "STUB_OUTP_IODELAY_S");
|
rc = add_connpt_name(model, y, x, "STUB_OUTP_IODELAY_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
for (i = 1; i <= 4; i++) {
|
for (i = 1; i <= 4; i++) {
|
||||||
rc = add_connpt_2(model, y, x, pf("Q%i_ILOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("Q%i_ILOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, pf("D%i_OLOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("D%i_OLOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, pf("T%i_OLOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("T%i_OLOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, pf("SHIFTIN%i_OLOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("SHIFTIN%i_OLOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, pf("SHIFTOUT%i_OLOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("SHIFTOUT%i_OLOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (i = 0; i <= 1; i++) {
|
for (i = 0; i <= 1; i++) {
|
||||||
rc = add_connpt_2(model, y, x, pf("CFB%i_ILOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("CFB%i_ILOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, pf("CLK%i_ILOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("CLK%i_ILOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, pf("CLK%i_OLOGIC_SITE", i), "", "_S");
|
rc = add_connpt_2(model, y, x, pf("CLK%i_OLOGIC_SITE", i), "", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -110,29 +111,29 @@ static int init_iologic_ports(struct fpga_model* model, int y, int x, enum which
|
||||||
"VALID_ILOGIC_SITE", "" };
|
"VALID_ILOGIC_SITE", "" };
|
||||||
|
|
||||||
for (i = 0; mcb_2[i][0]; i++) {
|
for (i = 0; mcb_2[i][0]; i++) {
|
||||||
rc = add_connpt_2(model, y, x, mcb_2[i], "", "_S");
|
rc = add_connpt_2(model, y, x, mcb_2[i], "", "_S", dup_warn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rc = add_connpt_name(model, y, x, "DATAOUT2_IODELAY_SITE");
|
rc = add_connpt_name(model, y, x, "DATAOUT2_IODELAY_SITE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "DATAOUT2_IODELAY2_SITE_S");
|
rc = add_connpt_name(model, y, x, "DATAOUT2_IODELAY2_SITE_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
for (i = 0; i <= 2; i++) {
|
for (i = 0; i <= 2; i++) {
|
||||||
rc = add_connpt_2(model, y, x, pf("IOI_CLK%iINTER", i),
|
rc = add_connpt_2(model, y, x, pf("IOI_CLK%iINTER", i),
|
||||||
"_M", "_S");
|
"_M", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (i = 0; i <= 1; i++) {
|
for (i = 0; i <= 1; i++) {
|
||||||
rc = add_connpt_2(model, y, x, pf("IOI_CLKDIST_IOCE%i", i),
|
rc = add_connpt_2(model, y, x, pf("IOI_CLKDIST_IOCE%i", i),
|
||||||
"_M", "_S");
|
"_M", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
rc = add_connpt_2(model, y, x, "IOI_CLKDIST_CLK0_ILOGIC", "_M", "_S");
|
rc = add_connpt_2(model, y, x, "IOI_CLKDIST_CLK0_ILOGIC", "_M", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, "IOI_CLKDIST_CLK0_OLOGIC", "_M", "_S");
|
rc = add_connpt_2(model, y, x, "IOI_CLKDIST_CLK0_OLOGIC", "_M", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_2(model, y, x, "IOI_CLKDIST_CLK1", "_M", "_S");
|
rc = add_connpt_2(model, y, x, "IOI_CLKDIST_CLK1", "_M", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
if (side == TOP_S || side == BOTTOM_S) {
|
if (side == TOP_S || side == BOTTOM_S) {
|
||||||
|
@ -147,11 +148,11 @@ static int init_iologic_ports(struct fpga_model* model, int y, int x, enum which
|
||||||
"IOI_MCB_DRPTRAIN", "" };
|
"IOI_MCB_DRPTRAIN", "" };
|
||||||
|
|
||||||
for (i = 0; mcb_2[i][0]; i++) {
|
for (i = 0; mcb_2[i][0]; i++) {
|
||||||
rc = add_connpt_2(model, y, x, mcb_2[i], "_M", "_S");
|
rc = add_connpt_2(model, y, x, mcb_2[i], "_M", "_S", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (i = 0; mcb_1[i][0]; i++) {
|
for (i = 0; mcb_1[i][0]; i++) {
|
||||||
rc = add_connpt_name(model, y, x, mcb_1[i]);
|
rc = add_connpt_name(model, y, x, mcb_1[i], dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,36 +161,36 @@ xout:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_ports(struct fpga_model* model)
|
int init_ports(struct fpga_model* model, int dup_warn)
|
||||||
{
|
{
|
||||||
int x, y, i, j, k, row_num, row_pos, rc;
|
int x, y, i, j, k, row_num, row_pos, rc;
|
||||||
|
|
||||||
// inner and outer IO tiles (ILOGIC/ILOGIC/IODELAY)
|
// inner and outer IO tiles (ILOGIC/ILOGIC/IODELAY)
|
||||||
for (x = LEFT_SIDE_WIDTH; x < model->x_width - RIGHT_SIDE_WIDTH; x++) {
|
for (x = LEFT_SIDE_WIDTH; x < model->x_width - RIGHT_SIDE_WIDTH; x++) {
|
||||||
if (has_device(model, TOP_OUTER_IO, x, DEV_ILOGIC)) {
|
if (has_device(model, TOP_OUTER_IO, x, DEV_ILOGIC)) {
|
||||||
rc = init_iologic_ports(model, TOP_OUTER_IO, x, TOP_S);
|
rc = init_iologic_ports(model, TOP_OUTER_IO, x, TOP_S, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
if (has_device(model, TOP_INNER_IO, x, DEV_ILOGIC)) {
|
if (has_device(model, TOP_INNER_IO, x, DEV_ILOGIC)) {
|
||||||
rc = init_iologic_ports(model, TOP_INNER_IO, x, TOP_S);
|
rc = init_iologic_ports(model, TOP_INNER_IO, x, TOP_S, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
if (has_device(model, model->y_height - BOT_INNER_IO, x, DEV_ILOGIC)) {
|
if (has_device(model, model->y_height - BOT_INNER_IO, x, DEV_ILOGIC)) {
|
||||||
rc = init_iologic_ports(model, model->y_height - BOT_INNER_IO, x, BOTTOM_S);
|
rc = init_iologic_ports(model, model->y_height - BOT_INNER_IO, x, BOTTOM_S, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
if (has_device(model, model->y_height - BOT_OUTER_IO, x, DEV_ILOGIC)) {
|
if (has_device(model, model->y_height - BOT_OUTER_IO, x, DEV_ILOGIC)) {
|
||||||
rc = init_iologic_ports(model, model->y_height - BOT_OUTER_IO, x, BOTTOM_S);
|
rc = init_iologic_ports(model, model->y_height - BOT_OUTER_IO, x, BOTTOM_S, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||||
if (has_device(model, y, LEFT_IO_DEVS, DEV_ILOGIC)) {
|
if (has_device(model, y, LEFT_IO_DEVS, DEV_ILOGIC)) {
|
||||||
rc = init_iologic_ports(model, y, LEFT_IO_DEVS, LEFT_S);
|
rc = init_iologic_ports(model, y, LEFT_IO_DEVS, LEFT_S, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
if (has_device(model, y, model->x_width - RIGHT_IO_DEVS_O, DEV_ILOGIC)) {
|
if (has_device(model, y, model->x_width - RIGHT_IO_DEVS_O, DEV_ILOGIC)) {
|
||||||
rc = init_iologic_ports(model, y, model->x_width - RIGHT_IO_DEVS_O, RIGHT_S);
|
rc = init_iologic_ports(model, y, model->x_width - RIGHT_IO_DEVS_O, RIGHT_S, dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,20 +201,20 @@ int init_ports(struct fpga_model* model)
|
||||||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS,
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS,
|
||||||
model, y))
|
model, y))
|
||||||
continue;
|
continue;
|
||||||
rc = add_connpt_name(model, y, x, "VCC_WIRE");
|
rc = add_connpt_name(model, y, x, "VCC_WIRE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "GND_WIRE");
|
rc = add_connpt_name(model, y, x, "GND_WIRE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "KEEP1_WIRE");
|
rc = add_connpt_name(model, y, x, "KEEP1_WIRE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "FAN");
|
rc = add_connpt_name(model, y, x, "FAN", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "FAN_B");
|
rc = add_connpt_name(model, y, x, "FAN_B", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
if (!is_atyx(YX_IO_ROUTING, model, y, x)) {
|
if (!is_atyx(YX_IO_ROUTING, model, y, x)) {
|
||||||
for (i = 0; i <= 1; i++) {
|
for (i = 0; i <= 1; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("GFAN%i", i));
|
rc = add_connpt_name(model, y, x, pf("GFAN%i", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -223,10 +224,10 @@ int init_ports(struct fpga_model* model)
|
||||||
// to the PLL, but elsewhere? Not clear what they
|
// to the PLL, but elsewhere? Not clear what they
|
||||||
// connect to...
|
// connect to...
|
||||||
rc = add_connpt_name(model, y, x,
|
rc = add_connpt_name(model, y, x,
|
||||||
logicin_s(X_A5, 1 /* routing_io */));
|
logicin_s(X_A5, 1 /* routing_io */), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x,
|
rc = add_connpt_name(model, y, x,
|
||||||
logicin_s(X_B4, 1 /* routing_io */));
|
logicin_s(X_B4, 1 /* routing_io */), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,30 +241,30 @@ int init_ports(struct fpga_model* model)
|
||||||
// pass 0 is ramb16, pass 1 and 2 are for ramb8
|
// pass 0 is ramb16, pass 1 and 2 are for ramb8
|
||||||
for (i = 0; i <= 2; i++) {
|
for (i = 0; i <= 2; i++) {
|
||||||
for (j = 'A'; j <= 'B'; j++) {
|
for (j = 'A'; j <= 'B'; j++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_CLK%c", pass_str[i], j));
|
rc = add_connpt_name(model, y, x, pf("%s_CLK%c", pass_str[i], j), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_EN%c", pass_str[i], j));
|
rc = add_connpt_name(model, y, x, pf("%s_EN%c", pass_str[i], j), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_REGCE%c", pass_str[i], j));
|
rc = add_connpt_name(model, y, x, pf("%s_REGCE%c", pass_str[i], j), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_RST%c", pass_str[i], j));
|
rc = add_connpt_name(model, y, x, pf("%s_RST%c", pass_str[i], j), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
for (k = 0; k <= (!i ? 3 : 1); k++) {
|
for (k = 0; k <= (!i ? 3 : 1); k++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_DIP%c%i", pass_str[i], j, k));
|
rc = add_connpt_name(model, y, x, pf("%s_DIP%c%i", pass_str[i], j, k), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_DOP%c%i", pass_str[i], j, k));
|
rc = add_connpt_name(model, y, x, pf("%s_DOP%c%i", pass_str[i], j, k), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_WE%c%i", pass_str[i], j, k));
|
rc = add_connpt_name(model, y, x, pf("%s_WE%c%i", pass_str[i], j, k), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (k = 0; k <= (!i ? 13 : 12); k++) {
|
for (k = 0; k <= (!i ? 13 : 12); k++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_ADDR%c%i", pass_str[i], j, k));
|
rc = add_connpt_name(model, y, x, pf("%s_ADDR%c%i", pass_str[i], j, k), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (k = 0; k <= (!i ? 31 : 15); k++) {
|
for (k = 0; k <= (!i ? 31 : 15); k++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_DI%c%i", pass_str[i], j, k));
|
rc = add_connpt_name(model, y, x, pf("%s_DI%c%i", pass_str[i], j, k), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_DO%c%i", pass_str[i], j, k));
|
rc = add_connpt_name(model, y, x, pf("%s_DO%c%i", pass_str[i], j, k), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,54 +280,54 @@ int init_ports(struct fpga_model* model)
|
||||||
|
|
||||||
is_in_row(model, y, &row_num, &row_pos);
|
is_in_row(model, y, &row_num, &row_pos);
|
||||||
if (!row_num && row_pos == LAST_POS_IN_ROW) {
|
if (!row_num && row_pos == LAST_POS_IN_ROW) {
|
||||||
rc = add_connpt_name(model, y, x, "CARRYIN_DSP48A1_SITE");
|
rc = add_connpt_name(model, y, x, "CARRYIN_DSP48A1_SITE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
for (i = 0; i <= 47; i++) {
|
for (i = 0; i <= 47; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("PCIN%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("PCIN%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = add_connpt_name(model, y, x, "CLK_DSP48A1_SITE");
|
rc = add_connpt_name(model, y, x, "CLK_DSP48A1_SITE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "CARRYOUT_DSP48A1_SITE");
|
rc = add_connpt_name(model, y, x, "CARRYOUT_DSP48A1_SITE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "CARRYOUTF_DSP48A1_SITE");
|
rc = add_connpt_name(model, y, x, "CARRYOUTF_DSP48A1_SITE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
for (i = 0; pref[i][0]; i++) {
|
for (i = 0; pref[i][0]; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%sCARRYIN_DSP48A1_SITE", pref[i]));
|
rc = add_connpt_name(model, y, x, pf("%sCARRYIN_DSP48A1_SITE", pref[i]), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
for (j = 0; seq[j][0]; j++) {
|
for (j = 0; seq[j][0]; j++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%s%s_DSP48A1_SITE", pref[i], seq[j]));
|
rc = add_connpt_name(model, y, x, pf("%s%s_DSP48A1_SITE", pref[i], seq[j]), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i <= 17; i++) {
|
for (i = 0; i <= 17; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("A%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("A%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("B%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("B%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("D%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("D%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("BCOUT%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("BCOUT%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (i = 0; i <= 47; i++) {
|
for (i = 0; i <= 47; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("C%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("C%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("P%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("P%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("PCOUT%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("PCOUT%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (i = 0; i <= 35; i++) {
|
for (i = 0; i <= 35; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("M%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("M%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
for (i = 0; i <= 7; i++) {
|
for (i = 0; i <= 7; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("OPMODE%i_DSP48A1_SITE", i));
|
rc = add_connpt_name(model, y, x, pf("OPMODE%i_DSP48A1_SITE", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,44 +341,44 @@ int init_ports(struct fpga_model* model)
|
||||||
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) {
|
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) {
|
||||||
// The first SLICEM on the bottom has a given C_IN port.
|
// The first SLICEM on the bottom has a given C_IN port.
|
||||||
if (is_aty(Y_INNER_BOTTOM, model, y+3)) {
|
if (is_aty(Y_INNER_BOTTOM, model, y+3)) {
|
||||||
rc = add_connpt_name(model, y, x, "M_CIN");
|
rc = add_connpt_name(model, y, x, "M_CIN", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
rc = add_connpt_name(model, y, x, "M_COUT");
|
rc = add_connpt_name(model, y, x, "M_COUT", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, "M_WE");
|
rc = add_connpt_name(model, y, x, "M_WE", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
for (i = 'A'; i <= 'D'; i++) {
|
for (i = 'A'; i <= 'D'; i++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("M_%cI", i));
|
rc = add_connpt_name(model, y, x, pf("M_%cI", i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
pref[0] = "M";
|
pref[0] = "M";
|
||||||
pref[1] = "X";
|
pref[1] = "X";
|
||||||
} else { // LOGIC_XL
|
} else { // LOGIC_XL
|
||||||
rc = add_connpt_name(model, y, x, "XL_COUT");
|
rc = add_connpt_name(model, y, x, "XL_COUT", dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
pref[0] = "L";
|
pref[0] = "L";
|
||||||
pref[1] = "XX";
|
pref[1] = "XX";
|
||||||
}
|
}
|
||||||
for (k = 0; k <= 1; k++) {
|
for (k = 0; k <= 1; k++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_CE", pref[k]));
|
rc = add_connpt_name(model, y, x, pf("%s_CE", pref[k]), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_SR", pref[k]));
|
rc = add_connpt_name(model, y, x, pf("%s_SR", pref[k]), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_CLK", pref[k]));
|
rc = add_connpt_name(model, y, x, pf("%s_CLK", pref[k]), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
for (i = 'A'; i <= 'D'; i++) {
|
for (i = 'A'; i <= 'D'; i++) {
|
||||||
for (j = 1; j <= 6; j++) {
|
for (j = 1; j <= 6; j++) {
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_%c%i", pref[k], i, j));
|
rc = add_connpt_name(model, y, x, pf("%s_%c%i", pref[k], i, j), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_%c", pref[k], i));
|
rc = add_connpt_name(model, y, x, pf("%s_%c", pref[k], i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_%cMUX", pref[k], i));
|
rc = add_connpt_name(model, y, x, pf("%s_%cMUX", pref[k], i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_%cQ", pref[k], i));
|
rc = add_connpt_name(model, y, x, pf("%s_%cQ", pref[k], i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
rc = add_connpt_name(model, y, x, pf("%s_%cX", pref[k], i));
|
rc = add_connpt_name(model, y, x, pf("%s_%cX", pref[k], i), dup_warn);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
482
model_switches.c
482
model_switches.c
|
@ -15,10 +15,15 @@ static int init_north_south_dirwire_term(struct fpga_model* model);
|
||||||
static int init_iologic_switches(struct fpga_model* model);
|
static int init_iologic_switches(struct fpga_model* model);
|
||||||
static int init_logic_switches(struct fpga_model* model);
|
static int init_logic_switches(struct fpga_model* model);
|
||||||
|
|
||||||
int init_switches(struct fpga_model* model)
|
int init_switches(struct fpga_model* model, int routing_sw)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (routing_sw) {
|
||||||
|
rc = init_routing_switches(model);
|
||||||
|
if (rc) goto xout;
|
||||||
|
}
|
||||||
|
|
||||||
rc = init_logic_switches(model);
|
rc = init_logic_switches(model);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
|
@ -34,10 +39,6 @@ int init_switches(struct fpga_model* model)
|
||||||
rc = init_io_switches(model);
|
rc = init_io_switches(model);
|
||||||
if (rc) goto xout;
|
if (rc) goto xout;
|
||||||
|
|
||||||
#if 0
|
|
||||||
rc = init_routing_switches(model);
|
|
||||||
if (rc) goto xout;
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
xout:
|
xout:
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -1671,238 +1672,279 @@ xout:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_routing_switches(struct fpga_model* model)
|
static int init_routing_tile(struct fpga_model* model, int y, int x)
|
||||||
{
|
{
|
||||||
int x, y, i, j, routing_io, rc;
|
int i, j, routing_io, rc;
|
||||||
struct set_of_switches dir_EB_switches;
|
struct set_of_switches dir_EB_switches;
|
||||||
enum wire_type wire;
|
enum wire_type wire;
|
||||||
struct fpga_tile* tile;
|
struct fpga_tile* tile;
|
||||||
const char* gfan_s, *gclk_s;
|
const char* gfan_s, *gclk_s;
|
||||||
|
|
||||||
|
tile = YX_TILE(model, y, x);
|
||||||
|
routing_io = (tile->type == IO_ROUTING || tile->type == ROUTING_IO_L);
|
||||||
|
gfan_s = routing_io ? "INT_IOI_GFAN%i" : "GFAN%i";
|
||||||
|
|
||||||
|
// GND
|
||||||
|
for (i = 0; i <= 1; i++) {
|
||||||
|
rc = add_switch(model, y, x, "GND_WIRE",
|
||||||
|
pf(gfan_s, i), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
rc = add_switch(model, y, x, "GND_WIRE", "SR1", 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// VCC
|
||||||
|
{ int vcc_dest[] = {
|
||||||
|
X_A3, X_A4, X_A5, X_A6, X_B3, X_B4, X_B5, X_B6,
|
||||||
|
X_C3, X_C4, X_C5, X_C6, X_D3, X_D4, X_D5, X_D6,
|
||||||
|
M_A3, M_A4, M_A5, M_A6, M_B3, M_B4, M_B5, M_B6,
|
||||||
|
M_C3, M_C4, M_C5, M_C6, M_D3, M_D4, M_D5, M_D6 };
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(vcc_dest)/sizeof(vcc_dest[0]); i++) {
|
||||||
|
rc = add_switch(model, y, x, "VCC_WIRE",
|
||||||
|
logicin_s(vcc_dest[i], routing_io), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}}
|
||||||
|
|
||||||
|
// KEEP1
|
||||||
|
for (i = X_A1; i <= M_WE; i++) {
|
||||||
|
rc = add_switch(model, y, x, "KEEP1_WIRE",
|
||||||
|
logicin_s(i, routing_io), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
rc = add_switch(model, y, x, "KEEP1_WIRE", "FAN_B", 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// VCC and KEEP1 to CLK0:1, SR0:1, GFAN0:1
|
||||||
|
{ static const char* src[] = {"VCC_WIRE", "KEEP1_WIRE"};
|
||||||
|
for (i = 0; i <= 1; i++)
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x, src[i],
|
||||||
|
pf("CLK%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = add_switch(model, y, x, src[i],
|
||||||
|
pf("SR%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
src[i], pf(gfan_s, j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GCLK0:15 -> CLK0:1, GFAN0:1/SR0:1
|
||||||
|
if (tile->type == ROUTING_BRK
|
||||||
|
|| tile->type == BRAM_ROUTING_BRK)
|
||||||
|
gclk_s = "GCLK%i_BRK";
|
||||||
|
else
|
||||||
|
gclk_s = "GCLK%i";
|
||||||
|
for (i = 0; i <= 15; i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x, pf(gclk_s, i),
|
||||||
|
pf("CLK%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
pf(gclk_s, i),
|
||||||
|
(i < 8) ? pf(gfan_s, j) : pf("SR%i", j),
|
||||||
|
0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FAN_B to SR0:1
|
||||||
|
for (i = 0; i <= 1; i++) {
|
||||||
|
rc = add_switch(model, y, x, "FAN_B",
|
||||||
|
pf("SR%i", i), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some logicin wires are singled out
|
||||||
|
{ int logic_singles[] = {X_CE, X_CX, X_DX,
|
||||||
|
M_AI, M_BI, M_CX, M_DX, M_WE};
|
||||||
|
for (i = 0; i < sizeof(logic_singles)/sizeof(logic_singles[0]); i++) {
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
pf("LOGICIN_B%i", logic_singles[i]),
|
||||||
|
pf("LOGICIN%i", logic_singles[i]), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}}
|
||||||
|
|
||||||
|
// connecting directional wires endpoints to logicin
|
||||||
|
rc = add_logicin_switches(model, y, x);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// connecting logicout back to directional wires
|
||||||
|
// beginning points (and some back to logicin)
|
||||||
|
rc = add_logicout_switches(model, y, x, routing_io);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// there are extra wires to send signals to logicin, or
|
||||||
|
// to share/multiply logicin signals
|
||||||
|
rc = add_logicio_extra(model, y, x, routing_io);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
|
// extra wires going to SR, CLK and GFAN
|
||||||
|
{ int to_sr[] = {X_BX, M_BX, M_DI};
|
||||||
|
for (i = 0; i < sizeof(to_sr)/sizeof(to_sr[0]); i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
pf("LOGICIN_B%i", to_sr[i]),
|
||||||
|
pf("SR%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{ int to_clk[] = {M_BX, M_CI};
|
||||||
|
for (i = 0; i < sizeof(to_clk)/sizeof(to_clk[0]); i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
pf("LOGICIN_B%i", to_clk[i]),
|
||||||
|
pf("CLK%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{ int to_gf[] = {M_AX, X_AX, M_CE, M_CI};
|
||||||
|
for (i = 0; i < sizeof(to_gf)/sizeof(to_gf[0]); i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
int bidir = !routing_io
|
||||||
|
&& ((!j && i < 2) || (j && i >= 2));
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
pf("LOGICIN_B%i", to_gf[i]),
|
||||||
|
pf(gfan_s, j), bidir);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
// connecting the directional wires from one's end
|
||||||
|
// to another one's beginning
|
||||||
|
wire = W_NN2;
|
||||||
|
do {
|
||||||
|
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN1(wire));
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
for (i = 0; i < dir_EB_switches.num_s; i++) {
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
dir_EB_switches.s[i].from,
|
||||||
|
dir_EB_switches.s[i].to, 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN2(wire));
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
for (i = 0; i < dir_EB_switches.num_s; i++) {
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
dir_EB_switches.s[i].from,
|
||||||
|
dir_EB_switches.s[i].to, 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN4(wire));
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
for (i = 0; i < dir_EB_switches.num_s; i++) {
|
||||||
|
rc = add_switch(model, y, x,
|
||||||
|
dir_EB_switches.s[i].from,
|
||||||
|
dir_EB_switches.s[i].to, 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
wire = W_CLOCKWISE(wire);
|
||||||
|
} while (wire != W_NN2); // one full turn
|
||||||
|
|
||||||
|
// and finally, some end wires go to CLK, SR and GFAN
|
||||||
|
{ static const char* from[] = {"NR1E2", "WR1E2"};
|
||||||
|
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x, from[i],
|
||||||
|
pf("CLK%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = add_switch(model, y, x, from[i],
|
||||||
|
pf("SR%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{ static const char* from[] = {"ER1E1", "SR1E1"};
|
||||||
|
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x, from[i],
|
||||||
|
pf("CLK%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
rc = add_switch(model, y, x, from[i],
|
||||||
|
pf(gfan_s, j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{ static const char* from[] = {"NR1E1", "WR1E1"};
|
||||||
|
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x, from[i],
|
||||||
|
pf(gfan_s, j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
{ static const char* from[] = {"ER1E2", "SR1E2"};
|
||||||
|
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
||||||
|
for (j = 0; j <= 1; j++) {
|
||||||
|
rc = add_switch(model, y, x, from[i],
|
||||||
|
pf("SR%i", j), 0 /* bidir */);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init_routing_switches(struct fpga_model* model)
|
||||||
|
{
|
||||||
|
int x, y, rc;
|
||||||
|
|
||||||
for (x = 0; x < model->x_width; x++) {
|
for (x = 0; x < model->x_width; x++) {
|
||||||
if (!is_atx(X_ROUTING_COL, model, x))
|
if (!is_atx(X_ROUTING_COL, model, x))
|
||||||
continue;
|
continue;
|
||||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
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;
|
||||||
|
rc = init_routing_tile(model, y, x);
|
||||||
|
if (rc) FAIL(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int replicate_routing_switches(struct fpga_model* model)
|
||||||
|
{
|
||||||
|
struct fpga_tile* tile;
|
||||||
|
int x, y, first_y, first_x, rc;
|
||||||
|
|
||||||
|
first_y = -1;
|
||||||
|
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,
|
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS,
|
||||||
model, y))
|
model, y))
|
||||||
continue;
|
continue;
|
||||||
tile = YX_TILE(model, y, x);
|
tile = YX_TILE(model, y, x);
|
||||||
routing_io = (tile->type == IO_ROUTING || tile->type == ROUTING_IO_L);
|
// Some tiles are different so we cannot include
|
||||||
gfan_s = routing_io ? "INT_IOI_GFAN%i" : "GFAN%i";
|
// them in the high-speed replication scheme.
|
||||||
|
if (tile->type == IO_ROUTING || tile->type == ROUTING_IO_L
|
||||||
// GND
|
|| tile->type == ROUTING_BRK || tile->type == BRAM_ROUTING_BRK) {
|
||||||
for (i = 0; i <= 1; i++) {
|
rc = init_routing_tile(model, y, x);
|
||||||
rc = add_switch(model, y, x, "GND_WIRE",
|
if (rc) FAIL(rc);
|
||||||
pf(gfan_s, i), 0 /* bidir */);
|
continue;
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
}
|
||||||
rc = add_switch(model, y, x, "GND_WIRE", "SR1",
|
if (first_y == -1) {
|
||||||
0 /* bidir */);
|
first_y = y;
|
||||||
if (rc) goto xout;
|
first_x = x;
|
||||||
|
rc = init_routing_tile(model, y, x);
|
||||||
// VCC
|
if (rc) FAIL(rc);
|
||||||
{ int vcc_dest[] = {
|
continue;
|
||||||
X_A3, X_A4, X_A5, X_A6, X_B3, X_B4, X_B5, X_B6,
|
|
||||||
X_C3, X_C4, X_C5, X_C6, X_D3, X_D4, X_D5, X_D6,
|
|
||||||
M_A3, M_A4, M_A5, M_A6, M_B3, M_B4, M_B5, M_B6,
|
|
||||||
M_C3, M_C4, M_C5, M_C6, M_D3, M_D4, M_D5, M_D6 };
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(vcc_dest)/sizeof(vcc_dest[0]); i++) {
|
|
||||||
rc = add_switch(model, y, x, "VCC_WIRE",
|
|
||||||
logicin_s(vcc_dest[i], routing_io),
|
|
||||||
0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}}
|
|
||||||
|
|
||||||
// KEEP1
|
|
||||||
for (i = X_A1; i <= M_WE; i++) {
|
|
||||||
rc = add_switch(model, y, x, "KEEP1_WIRE",
|
|
||||||
logicin_s(i, routing_io),
|
|
||||||
0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
}
|
||||||
rc = add_switch(model, y, x, "KEEP1_WIRE", "FAN_B",
|
rc = replicate_switches_and_names(model,
|
||||||
0 /* bidir */);
|
first_y, first_x, y, x);
|
||||||
if (rc) goto xout;
|
if (rc) FAIL(rc);
|
||||||
|
|
||||||
// VCC and KEEP1 to CLK0:1, SR0:1, GFAN0:1
|
|
||||||
{ static const char* src[] = {"VCC_WIRE", "KEEP1_WIRE"};
|
|
||||||
for (i = 0; i <= 1; i++)
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x, src[i],
|
|
||||||
pf("CLK%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
rc = add_switch(model, y, x, src[i],
|
|
||||||
pf("SR%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
src[i],
|
|
||||||
pf(gfan_s, j),
|
|
||||||
0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GCLK0:15 -> CLK0:1, GFAN0:1/SR0:1
|
|
||||||
if (tile->type == ROUTING_BRK
|
|
||||||
|| tile->type == BRAM_ROUTING_BRK)
|
|
||||||
gclk_s = "GCLK%i_BRK";
|
|
||||||
else
|
|
||||||
gclk_s = "GCLK%i";
|
|
||||||
for (i = 0; i <= 15; i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
pf(gclk_s, i),
|
|
||||||
pf("CLK%i", j),
|
|
||||||
0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
pf(gclk_s, i),
|
|
||||||
(i < 8)
|
|
||||||
? pf(gfan_s, j)
|
|
||||||
: pf("SR%i", j),
|
|
||||||
0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FAN_B to SR0:1
|
|
||||||
for (i = 0; i <= 1; i++) {
|
|
||||||
rc = add_switch(model, y, x, "FAN_B",
|
|
||||||
pf("SR%i", i), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// some logicin wires are singled out
|
|
||||||
{ int logic_singles[] = {X_CE, X_CX, X_DX,
|
|
||||||
M_AI, M_BI, M_CX, M_DX, M_WE};
|
|
||||||
for (i = 0; i < sizeof(logic_singles)/sizeof(logic_singles[0]); i++) {
|
|
||||||
rc = add_switch(model, y, x, pf("LOGICIN_B%i", logic_singles[i]),
|
|
||||||
pf("LOGICIN%i", logic_singles[i]), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}}
|
|
||||||
|
|
||||||
// connecting directional wires endpoints to logicin
|
|
||||||
rc = add_logicin_switches(model, y, x);
|
|
||||||
if (rc) goto xout;
|
|
||||||
|
|
||||||
// connecting logicout back to directional wires
|
|
||||||
// beginning points (and some back to logicin)
|
|
||||||
rc = add_logicout_switches(model, y, x, routing_io);
|
|
||||||
if (rc) goto xout;
|
|
||||||
|
|
||||||
// there are extra wires to send signals to logicin, or
|
|
||||||
// to share/multiply logicin signals
|
|
||||||
rc = add_logicio_extra(model, y, x, routing_io);
|
|
||||||
if (rc) goto xout;
|
|
||||||
|
|
||||||
// extra wires going to SR, CLK and GFAN
|
|
||||||
{ int to_sr[] = {X_BX, M_BX, M_DI};
|
|
||||||
for (i = 0; i < sizeof(to_sr)/sizeof(to_sr[0]); i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
pf("LOGICIN_B%i", to_sr[i]),
|
|
||||||
pf("SR%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
{ int to_clk[] = {M_BX, M_CI};
|
|
||||||
for (i = 0; i < sizeof(to_clk)/sizeof(to_clk[0]); i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
pf("LOGICIN_B%i", to_clk[i]),
|
|
||||||
pf("CLK%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
{ int to_gf[] = {M_AX, X_AX, M_CE, M_CI};
|
|
||||||
for (i = 0; i < sizeof(to_gf)/sizeof(to_gf[0]); i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
int bidir = !routing_io
|
|
||||||
&& ((!j && i < 2) || (j && i >= 2));
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
pf("LOGICIN_B%i", to_gf[i]),
|
|
||||||
pf(gfan_s, j), bidir);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
// connecting the directional wires from one's end
|
|
||||||
// to another one's beginning
|
|
||||||
wire = W_NN2;
|
|
||||||
do {
|
|
||||||
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN1(wire));
|
|
||||||
if (rc) goto xout;
|
|
||||||
for (i = 0; i < dir_EB_switches.num_s; i++) {
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
dir_EB_switches.s[i].from,
|
|
||||||
dir_EB_switches.s[i].to, 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN2(wire));
|
|
||||||
if (rc) goto xout;
|
|
||||||
for (i = 0; i < dir_EB_switches.num_s; i++) {
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
dir_EB_switches.s[i].from,
|
|
||||||
dir_EB_switches.s[i].to, 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN4(wire));
|
|
||||||
if (rc) goto xout;
|
|
||||||
for (i = 0; i < dir_EB_switches.num_s; i++) {
|
|
||||||
rc = add_switch(model, y, x,
|
|
||||||
dir_EB_switches.s[i].from,
|
|
||||||
dir_EB_switches.s[i].to, 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
|
|
||||||
wire = W_CLOCKWISE(wire);
|
|
||||||
} while (wire != W_NN2); // one full turn
|
|
||||||
|
|
||||||
// and finally, some end wires go to CLK, SR and GFAN
|
|
||||||
{ static const char* from[] = {"NR1E2", "WR1E2"};
|
|
||||||
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x, from[i],
|
|
||||||
pf("CLK%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
rc = add_switch(model, y, x, from[i],
|
|
||||||
pf("SR%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
{ static const char* from[] = {"ER1E1", "SR1E1"};
|
|
||||||
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x, from[i],
|
|
||||||
pf("CLK%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
rc = add_switch(model, y, x, from[i],
|
|
||||||
pf(gfan_s, j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
{ static const char* from[] = {"NR1E1", "WR1E1"};
|
|
||||||
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x, from[i],
|
|
||||||
pf(gfan_s, j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
{ static const char* from[] = {"ER1E2", "SR1E2"};
|
|
||||||
for (i = 0; i < sizeof(from)/sizeof(from[0]); i++) {
|
|
||||||
for (j = 0; j <= 1; j++) {
|
|
||||||
rc = add_switch(model, y, x, from[i],
|
|
||||||
pf("SR%i", j), 0 /* bidir */);
|
|
||||||
if (rc) goto xout;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
xout:
|
fail:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user