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
|
||||
.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 \
|
||||
-Wno-format-zero-length -Ofast
|
||||
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;
|
||||
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);
|
||||
for (i = 0; i < num_dests; i++) {
|
||||
if (!i)
|
||||
|
@ -132,16 +134,22 @@ static int printf_switchtree(struct fpga_model* model, int y, int x,
|
|||
to_str);
|
||||
idx = fpga_switch_next(model, y, x, idx, SW_TO);
|
||||
}
|
||||
#endif
|
||||
|
||||
idx = fpga_switch_first(model, y, x, start, SW_FROM);
|
||||
if (idx != NO_SWITCH)
|
||||
printf("%.*s| switches to:\n", indent, s_spaces);
|
||||
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);
|
||||
#if 0
|
||||
printf("%.*s %s %s\n", indent, s_spaces,
|
||||
fpga_switch_is_bidir(model, y, x, idx) ? "<->" : "->",
|
||||
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);
|
||||
idx = fpga_switch_next(model, y, x, idx, SW_FROM);
|
||||
}
|
||||
|
@ -150,15 +158,46 @@ fail:
|
|||
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)
|
||||
{
|
||||
struct fpga_model model;
|
||||
struct fpga_device* P46_dev, *P48_dev, *logic_dev;
|
||||
int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, rc;
|
||||
struct test_state tstate;
|
||||
struct sw_chain chain;
|
||||
struct swchain_conns conns;
|
||||
// struct sw_chain chain;
|
||||
// struct swchain_conns conns;
|
||||
char tmp_str[128];
|
||||
swidx_t switch_chain[MAX_SW_CHAIN_SIZE];
|
||||
int switch_chain_size;
|
||||
|
||||
printf("\n");
|
||||
printf("O fpgatools automatic test suite. Be welcome and be "
|
||||
|
@ -214,16 +253,28 @@ int main(int argc, char** argv)
|
|||
if (rc) FAIL(rc);
|
||||
|
||||
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_swconns(&model, P46_y, P46_x, P46_dev->iob.pinw_out_I);
|
||||
|
||||
|
||||
conns.model = &model;
|
||||
conns.y = P46_y;
|
||||
conns.x = P46_x;
|
||||
conns.start_switch = P46_dev->iob.pinw_out_I;
|
||||
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;
|
||||
|
||||
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.x = conns.dest_x;
|
||||
conns2.start_switch = tmp_str;
|
||||
|
||||
while (fpga_switch_conns_enum(&conns2) != NO_CONN) {
|
||||
if (is_atyx(YX_ROUTING_TILE, &model, conns2.dest_y, conns2.dest_x)) {
|
||||
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",
|
||||
conns2.chain.chain_size, conns2.connpt_dest_start,
|
||||
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);
|
||||
printf_swconns(&model, conns2.dest_y, conns2.dest_x, tmp_str);
|
||||
|
||||
conns3.model = &model;
|
||||
conns3.y = conns2.dest_y;
|
||||
conns3.x = conns2.dest_x;
|
||||
conns3.start_switch = tmp_str;
|
||||
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",
|
||||
conns3.chain.chain_size, conns3.connpt_dest_start,
|
||||
conns3.num_dests, conns3.dest_i, conns3.dest_y, conns3.dest_x, conns3.dest_str);
|
||||
if (is_atyx(YX_ROUTING_TO_FABLOGIC, &model, conns3.dest_y, conns3.dest_x)) {
|
||||
printf("route to y%02i x%02i\n", conns3.dest_y, conns3.dest_x);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
printf("P48 O pinw %s\n", P48_dev->iob.pinw_in_O);
|
||||
|
||||
|
|
97
control.c
97
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.
|
||||
tile = YX_TILE(model, y, x);
|
||||
for (i = 0; i < tile->num_switches; i++) {
|
||||
connpt_o = (from_to == SW_FROM)
|
||||
? SWITCH_FROM(tile->switches[i])
|
||||
: SWITCH_TO(tile->switches[i]);
|
||||
connpt_o = SW_I(tile->switches[i], from_to);
|
||||
if (tile->conn_point_names[connpt_o*2+1] == name_i)
|
||||
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;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
connpt_o = (from_to == SW_FROM)
|
||||
? SWITCH_FROM(tile->switches[last])
|
||||
: SWITCH_TO(tile->switches[last]);
|
||||
connpt_o = SW_I(tile->switches[last], from_to);
|
||||
name_i = tile->conn_point_names[connpt_o*2+1];
|
||||
|
||||
for (i = search_beg; i < tile->num_switches; i++) {
|
||||
connpt_o = (from_to == SW_FROM)
|
||||
? SWITCH_FROM(tile->switches[i])
|
||||
: SWITCH_TO(tile->switches[i]);
|
||||
connpt_o = SW_I(tile->switches[i], from_to);
|
||||
if (tile->conn_point_names[connpt_o*2+1] == name_i)
|
||||
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);
|
||||
}
|
||||
|
||||
#define NUM_CONNPT_BUFS 16
|
||||
#define NUM_CONNPT_BUFS 64
|
||||
#define CONNPT_BUF_SIZE 128
|
||||
|
||||
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)
|
||||
{
|
||||
uint32_t sw = YX_TILE(model, y, x)->switches[swidx];
|
||||
return connpt_str(model, y, x,
|
||||
(from_to == SW_FROM) ? SWITCH_FROM(sw) : SWITCH_TO(sw));
|
||||
return connpt_str(model, y, x, SW_I(sw, from_to));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
swidx_t idx;
|
||||
struct fpga_tile* tile;
|
||||
int child_from_to, i;
|
||||
|
||||
if (chain->start_switch != SW_CHAIN_NEXT) {
|
||||
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;
|
||||
}
|
||||
// look for children
|
||||
tile = YX_TILE(chain->model, chain->y, chain->x);
|
||||
while (1) {
|
||||
idx = fpga_switch_first(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->from_to);
|
||||
chain->chain[chain->chain_size-1] = fpga_switch_next(
|
||||
chain->model, chain->y, chain->x,
|
||||
chain->chain[chain->chain_size-1], chain->from_to);
|
||||
child_from_to = SW_I(tile->switches[chain->chain[chain->chain_size-1]],
|
||||
!chain->from_to);
|
||||
if (idx != NO_SWITCH) {
|
||||
// If we have the same from-switch already among the
|
||||
// parents, don't fall into endless recursion...
|
||||
for (i = 0; i < chain->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;
|
||||
}
|
||||
chain->first_round = 1; // back to first round at new level
|
||||
// back to first round at new level
|
||||
chain->first_round = 1;
|
||||
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) {
|
||||
chain->chain_size = 0;
|
||||
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,
|
||||
int connpt_dest_idx, int* dest_y, int* dest_x);
|
||||
|
||||
typedef int swidx_t;
|
||||
|
||||
// SW_FROM and SW_TO values are chosen such that ! inverts them.
|
||||
#define SW_FROM 0
|
||||
#define SW_TO 1
|
||||
typedef int swidx_t; // swidx_t is an index into the uint32_t switches array
|
||||
|
||||
// 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,
|
||||
|
@ -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,
|
||||
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 MAX_SW_CHAIN_SIZE 32
|
||||
#define MAX_SW_CHAIN_SIZE 32 // largest seen so far was 10
|
||||
|
||||
struct sw_chain
|
||||
{
|
||||
|
|
2
helper.h
2
helper.h
|
@ -115,6 +115,8 @@ struct hashed_strarray
|
|||
#define STRIDX_64K 0xFFFF
|
||||
#define STRIDX_1M 1000000
|
||||
|
||||
typedef uint16_t str16_t;
|
||||
|
||||
int strarray_init(struct hashed_strarray* array, int highest_index);
|
||||
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
|
||||
#define YX_ROUTING_TILE 0x0001
|
||||
#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);
|
||||
|
||||
|
@ -387,8 +391,14 @@ struct fpga_device
|
|||
#define SWITCH_ON 0x80000000
|
||||
#define SWITCH_BIDIRECTIONAL 0x40000000
|
||||
#define SWITCH_MAX_CONNPT_O 0x7FFF // 15 bits
|
||||
#define SWITCH_FROM(u32) (((u32) >> 15) & SWITCH_MAX_CONNPT_O)
|
||||
#define SWITCH_TO(u32) ((u32) & SWITCH_MAX_CONNPT_O)
|
||||
#define SW_FROM_I(u32) (((u32) >> 15) & 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_CONN -1
|
||||
|
@ -435,23 +445,30 @@ void fpga_free_model(struct fpga_model* model);
|
|||
const char* fpga_tiletype_str(enum fpga_tile_type type);
|
||||
|
||||
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);
|
||||
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* wpref(struct fpga_model* model, int y, int x, const char* wire_name);
|
||||
char next_non_whitespace(const char* s);
|
||||
char last_major(const char* str, int cur_o);
|
||||
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_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,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
{
|
||||
int x_flags;
|
||||
|
|
|
@ -788,11 +788,11 @@ static int run_io_wires(struct fpga_model* model)
|
|||
for (i = 0; s[i][0]; i++) {
|
||||
struct w_net net1 = {
|
||||
1,
|
||||
{{ pf("BIOB_%s%%i", s[i]), 0, y, x },
|
||||
{ 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_INNER_%s%%i", s[i]), 0, y-3, 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;
|
||||
|
|
|
@ -57,37 +57,37 @@ static int init_iob(struct fpga_model* model, int y, int x,
|
|||
snprintf(tile->devs[idx].iob.pinw_in_O,
|
||||
sizeof(tile->devs[idx].iob.pinw_in_O),
|
||||
"%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);
|
||||
snprintf(tile->devs[idx].iob.pinw_in_T,
|
||||
sizeof(tile->devs[idx].iob.pinw_in_T),
|
||||
"%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);
|
||||
snprintf(tile->devs[idx].iob.pinw_out_I,
|
||||
sizeof(tile->devs[idx].iob.pinw_out_I),
|
||||
"%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);
|
||||
snprintf(tile->devs[idx].iob.pinw_out_PADOUT,
|
||||
sizeof(tile->devs[idx].iob.pinw_out_PADOUT),
|
||||
"%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);
|
||||
snprintf(tile->devs[idx].iob.pinw_in_DIFFI_IN,
|
||||
sizeof(tile->devs[idx].iob.pinw_in_DIFFI_IN),
|
||||
"%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);
|
||||
snprintf(tile->devs[idx].iob.pinw_in_DIFFO_IN,
|
||||
sizeof(tile->devs[idx].iob.pinw_in_DIFFO_IN),
|
||||
"%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);
|
||||
snprintf(tile->devs[idx].iob.pinw_out_DIFFO_OUT,
|
||||
sizeof(tile->devs[idx].iob.pinw_out_DIFFO_OUT),
|
||||
"%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 (!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),
|
||||
"%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);
|
||||
return 0;
|
||||
fail:
|
||||
|
|
124
model_helper.c
124
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 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,
|
||||
1 /* warn_if_duplicate */,
|
||||
return _add_connpt_name(model, y, x, connpt_name, dup_warn,
|
||||
0 /* name_i */, 0 /* conn_point_o */);
|
||||
}
|
||||
|
||||
#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,
|
||||
const char* connpt_name, int warn_if_duplicate, uint16_t* name_i,
|
||||
int* conn_point_o)
|
||||
|
@ -117,18 +131,7 @@ static int _add_connpt_name(struct fpga_model* model, int y, int x,
|
|||
return 0;
|
||||
}
|
||||
// This is the first connection under name, add name.
|
||||
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) {
|
||||
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++;
|
||||
connpt_names_array_append(tile, _name_i);
|
||||
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,
|
||||
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];
|
||||
int rc;
|
||||
|
||||
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;
|
||||
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;
|
||||
return 0;
|
||||
xout:
|
||||
|
@ -322,9 +326,13 @@ xout:
|
|||
return rc;
|
||||
}
|
||||
|
||||
#define SWITCH_ALLOC_INCREMENT 64
|
||||
#define SWITCH_ALLOC_INCREMENT 256
|
||||
|
||||
#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,
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
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) {
|
||||
from_connpt_o = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
to_connpt_o = -1;
|
||||
for (i = tile->num_conn_point_names-1; i >= 0; i--) {
|
||||
if (tile->conn_point_names[i*2+1] == to_idx) {
|
||||
to_connpt_o = i;
|
||||
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;
|
||||
from_connpt_o = tile->num_conn_point_names;
|
||||
connpt_names_array_append(tile, from_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
}
|
||||
#ifdef DBG_ALLOW_ADDPOINTS
|
||||
if (to_connpt_o == -1) {
|
||||
rc = add_connpt_name(model, y, x, to);
|
||||
if (rc) goto xout;
|
||||
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;
|
||||
}
|
||||
}
|
||||
to_connpt_o = tile->num_conn_point_names;
|
||||
connpt_names_array_append(tile, to_idx);
|
||||
}
|
||||
#endif
|
||||
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)
|
||||
new_switch |= SWITCH_BIDIRECTIONAL;
|
||||
|
||||
#ifdef CHECK_DUPLICATES
|
||||
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",
|
||||
|
@ -412,6 +410,7 @@ int add_switch(struct fpga_model* model, int y, int x, const char* from,
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!(tile->num_switches % SWITCH_ALLOC_INCREMENT)) {
|
||||
uint32_t* new_ptr = realloc(tile->switches,
|
||||
(tile->num_switches+SWITCH_ALLOC_INCREMENT)*sizeof(*tile->switches));
|
||||
|
@ -457,6 +456,35 @@ xout:
|
|||
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)
|
||||
{
|
||||
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);
|
||||
if (check & YX_IO_ROUTING
|
||||
&& (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;
|
||||
}
|
||||
|
||||
|
|
29
model_main.c
29
model_main.c
|
@ -8,8 +8,10 @@
|
|||
#include <stdarg.h>
|
||||
#include "model.h"
|
||||
|
||||
int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* columns,
|
||||
const char* left_wiring, const char* right_wiring)
|
||||
static int s_high_speed_replicate = 1;
|
||||
|
||||
int fpga_build_model(struct fpga_model* model, int fpga_rows,
|
||||
const char* columns, const char* left_wiring, const char* right_wiring)
|
||||
{
|
||||
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.
|
||||
|
||||
rc = init_tiles(model);
|
||||
if (rc) return rc;
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = init_devices(model);
|
||||
if (rc) return rc;
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = init_ports(model);
|
||||
if (rc) return rc;
|
||||
if (s_high_speed_replicate) {
|
||||
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);
|
||||
if (rc) return rc;
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
rc = init_switches(model);
|
||||
if (rc) return rc;
|
||||
rc = init_switches(model, /*routing_sw*/ !s_high_speed_replicate);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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;
|
||||
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++) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
{
|
||||
|
@ -110,29 +111,29 @@ static int init_iologic_ports(struct fpga_model* model, int y, int x, enum which
|
|||
"VALID_ILOGIC_SITE", "" };
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
for (i = 0; i <= 2; i++) {
|
||||
rc = add_connpt_2(model, y, x, pf("IOI_CLK%iINTER", i),
|
||||
"_M", "_S");
|
||||
"_M", "_S", dup_warn);
|
||||
if (rc) goto xout;
|
||||
}
|
||||
for (i = 0; i <= 1; i++) {
|
||||
rc = add_connpt_2(model, y, x, pf("IOI_CLKDIST_IOCE%i", i),
|
||||
"_M", "_S");
|
||||
"_M", "_S", dup_warn);
|
||||
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;
|
||||
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;
|
||||
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 (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", "" };
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -160,36 +161,36 @@ xout:
|
|||
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;
|
||||
|
||||
// inner and outer IO tiles (ILOGIC/ILOGIC/IODELAY)
|
||||
for (x = LEFT_SIDE_WIDTH; x < model->x_width - RIGHT_SIDE_WIDTH; x++) {
|
||||
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 (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 (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 (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;
|
||||
}
|
||||
}
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
|
@ -200,20 +201,20 @@ int init_ports(struct fpga_model* model)
|
|||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS,
|
||||
model, y))
|
||||
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;
|
||||
rc = add_connpt_name(model, y, x, "GND_WIRE");
|
||||
rc = add_connpt_name(model, y, x, "GND_WIRE", dup_warn);
|
||||
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;
|
||||
rc = add_connpt_name(model, y, x, "FAN");
|
||||
rc = add_connpt_name(model, y, x, "FAN", dup_warn);
|
||||
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 (!is_atyx(YX_IO_ROUTING, model, y, x)) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
|
@ -223,10 +224,10 @@ int init_ports(struct fpga_model* model)
|
|||
// to the PLL, but elsewhere? Not clear what they
|
||||
// connect to...
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -240,30 +241,30 @@ int init_ports(struct fpga_model* model)
|
|||
// pass 0 is ramb16, pass 1 and 2 are for ramb8
|
||||
for (i = 0; i <= 2; i++) {
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -279,54 +280,54 @@ int init_ports(struct fpga_model* model)
|
|||
|
||||
is_in_row(model, y, &row_num, &row_pos);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -340,44 +341,44 @@ int init_ports(struct fpga_model* model)
|
|||
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) {
|
||||
// The first SLICEM on the bottom has a given C_IN port.
|
||||
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;
|
||||
}
|
||||
rc = add_connpt_name(model, y, x, "M_COUT");
|
||||
rc = add_connpt_name(model, y, x, "M_COUT", dup_warn);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
pref[0] = "M";
|
||||
pref[1] = "X";
|
||||
} 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;
|
||||
pref[0] = "L";
|
||||
pref[1] = "XX";
|
||||
}
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
for (i = 'A'; i <= 'D'; i++) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
170
model_switches.c
170
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_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;
|
||||
|
||||
if (routing_sw) {
|
||||
rc = init_routing_switches(model);
|
||||
if (rc) goto xout;
|
||||
}
|
||||
|
||||
rc = init_logic_switches(model);
|
||||
if (rc) goto xout;
|
||||
|
||||
|
@ -34,10 +39,6 @@ int init_switches(struct fpga_model* model)
|
|||
rc = init_io_switches(model);
|
||||
if (rc) goto xout;
|
||||
|
||||
#if 0
|
||||
rc = init_routing_switches(model);
|
||||
if (rc) goto xout;
|
||||
#endif
|
||||
return 0;
|
||||
xout:
|
||||
return rc;
|
||||
|
@ -1671,21 +1672,14 @@ xout:
|
|||
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;
|
||||
enum wire_type wire;
|
||||
struct fpga_tile* tile;
|
||||
const char* gfan_s, *gclk_s;
|
||||
|
||||
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;
|
||||
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";
|
||||
|
@ -1694,11 +1688,10 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
for (i = 0; i <= 1; i++) {
|
||||
rc = add_switch(model, y, x, "GND_WIRE",
|
||||
pf(gfan_s, i), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
rc = add_switch(model, y, x, "GND_WIRE", "SR1",
|
||||
0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
rc = add_switch(model, y, x, "GND_WIRE", "SR1", 0 /* bidir */);
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// VCC
|
||||
{ int vcc_dest[] = {
|
||||
|
@ -1709,21 +1702,18 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
|
||||
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;
|
||||
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) goto xout;
|
||||
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) goto xout;
|
||||
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"};
|
||||
|
@ -1731,15 +1721,13 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
for (j = 0; j <= 1; j++) {
|
||||
rc = add_switch(model, y, x, src[i],
|
||||
pf("CLK%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
rc = add_switch(model, y, x, src[i],
|
||||
pf("SR%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
rc = add_switch(model, y, x,
|
||||
src[i],
|
||||
pf(gfan_s, j),
|
||||
0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
src[i], pf(gfan_s, j), 0 /* bidir */);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1751,18 +1739,14 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
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),
|
||||
pf("CLK%i", j),
|
||||
(i < 8) ? pf(gfan_s, j) : pf("SR%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;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1770,31 +1754,32 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
for (i = 0; i <= 1; i++) {
|
||||
rc = add_switch(model, y, x, "FAN_B",
|
||||
pf("SR%i", i), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
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]),
|
||||
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;
|
||||
if (rc) FAIL(rc);
|
||||
}}
|
||||
|
||||
// connecting directional wires endpoints to logicin
|
||||
rc = add_logicin_switches(model, y, x);
|
||||
if (rc) goto xout;
|
||||
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) goto xout;
|
||||
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) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
|
||||
// extra wires going to SR, CLK and GFAN
|
||||
{ int to_sr[] = {X_BX, M_BX, M_DI};
|
||||
|
@ -1803,7 +1788,7 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
rc = add_switch(model, y, x,
|
||||
pf("LOGICIN_B%i", to_sr[i]),
|
||||
pf("SR%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}}
|
||||
{ int to_clk[] = {M_BX, M_CI};
|
||||
|
@ -1812,7 +1797,7 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
rc = add_switch(model, y, x,
|
||||
pf("LOGICIN_B%i", to_clk[i]),
|
||||
pf("CLK%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}}
|
||||
{ int to_gf[] = {M_AX, X_AX, M_CE, M_CI};
|
||||
|
@ -1823,7 +1808,7 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
rc = add_switch(model, y, x,
|
||||
pf("LOGICIN_B%i", to_gf[i]),
|
||||
pf(gfan_s, j), bidir);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}}
|
||||
|
||||
|
@ -1832,30 +1817,30 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
wire = W_NN2;
|
||||
do {
|
||||
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN1(wire));
|
||||
if (rc) goto xout;
|
||||
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) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN2(wire));
|
||||
if (rc) goto xout;
|
||||
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) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
rc = build_dirwire_switches(&dir_EB_switches, W_TO_LEN4(wire));
|
||||
if (rc) goto xout;
|
||||
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) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
|
||||
wire = W_CLOCKWISE(wire);
|
||||
|
@ -1867,10 +1852,10 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
for (j = 0; j <= 1; j++) {
|
||||
rc = add_switch(model, y, x, from[i],
|
||||
pf("CLK%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
rc = add_switch(model, y, x, from[i],
|
||||
pf("SR%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}}
|
||||
{ static const char* from[] = {"ER1E1", "SR1E1"};
|
||||
|
@ -1878,10 +1863,10 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
for (j = 0; j <= 1; j++) {
|
||||
rc = add_switch(model, y, x, from[i],
|
||||
pf("CLK%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
rc = add_switch(model, y, x, from[i],
|
||||
pf(gfan_s, j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}}
|
||||
{ static const char* from[] = {"NR1E1", "WR1E1"};
|
||||
|
@ -1889,7 +1874,7 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
for (j = 0; j <= 1; j++) {
|
||||
rc = add_switch(model, y, x, from[i],
|
||||
pf(gfan_s, j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}}
|
||||
{ static const char* from[] = {"ER1E2", "SR1E2"};
|
||||
|
@ -1897,12 +1882,69 @@ static int init_routing_switches(struct fpga_model* model)
|
|||
for (j = 0; j <= 1; j++) {
|
||||
rc = add_switch(model, y, x, from[i],
|
||||
pf("SR%i", j), 0 /* bidir */);
|
||||
if (rc) goto xout;
|
||||
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++) {
|
||||
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;
|
||||
rc = init_routing_tile(model, y, x);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
xout:
|
||||
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,
|
||||
model, y))
|
||||
continue;
|
||||
tile = YX_TILE(model, y, x);
|
||||
// Some tiles are different so we cannot include
|
||||
// them in the high-speed replication scheme.
|
||||
if (tile->type == IO_ROUTING || tile->type == ROUTING_IO_L
|
||||
|| tile->type == ROUTING_BRK || tile->type == BRAM_ROUTING_BRK) {
|
||||
rc = init_routing_tile(model, y, x);
|
||||
if (rc) FAIL(rc);
|
||||
continue;
|
||||
}
|
||||
if (first_y == -1) {
|
||||
first_y = y;
|
||||
first_x = x;
|
||||
rc = init_routing_tile(model, y, x);
|
||||
if (rc) FAIL(rc);
|
||||
continue;
|
||||
}
|
||||
rc = replicate_switches_and_names(model,
|
||||
first_y, first_x, y, x);
|
||||
if (rc) FAIL(rc);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user