don't stop me now
This commit is contained in:
parent
eef694d733
commit
b1d665e84b
18
Makefile
18
Makefile
|
@ -77,7 +77,7 @@ xc6slx9_empty.fp: new_fp
|
|||
xc6slx9.svg: draw_svg_tiles
|
||||
./draw_svg_tiles | xmllint --pretty 1 - > $@
|
||||
|
||||
compare_all: compare.tiles compare.devices compare.conns compare.ports compare.sw
|
||||
compare_all: compare.tiles compare.devs compare.conns compare.ports compare.sw
|
||||
|
||||
compare.%: xc6slx9_empty.%
|
||||
@comm -1 -2 $< compare_other.$* > compare_$*_matching.txt
|
||||
|
@ -92,11 +92,11 @@ compare.%: xc6slx9_empty.%
|
|||
%.tiles: %.fp
|
||||
@cat $<|awk '{if ($$1=="tile" && $$4=="name") printf "%s %s %s\n",$$2,$$3,$$5}'|sort >$@
|
||||
|
||||
%.devices: %.fp
|
||||
@cat $<|awk '{if ($$1=="device") printf "%s %s %s\n",$$2,$$3,$$4}'|sort >$@
|
||||
%.devs: %.fp
|
||||
@cat $<|awk '{if ($$1=="dev") {if ($$6=="type") printf "%s %s %s %s\n",$$2,$$3,$$4,$$7; else printf "%s %s %s\n",$$2,$$3,$$4; }}'|sort >$@
|
||||
|
||||
%.nets: %.fp pair2net
|
||||
cat $<|awk '{if ($$1=="static_conn") printf "%s-%s-%s %s-%s-%s\n",$$2,$$3,$$4,$$5,$$6,$$7}' |./pair2net -|sort >$@
|
||||
cat $<|awk '{if ($$1=="conn") printf "%s-%s-%s %s-%s-%s\n",$$2,$$3,$$4,$$5,$$6,$$7}' |./pair2net -|sort >$@
|
||||
@echo Number of nets:
|
||||
@cat $@|wc -l
|
||||
@echo Number of connection points:
|
||||
|
@ -105,13 +105,13 @@ compare.%: xc6slx9_empty.%
|
|||
@cat $@|awk '{if (NF>max) max=NF} END {print max}'
|
||||
|
||||
%.conns: %.fp sort_seq merge_seq
|
||||
@cat $<|awk '{if ($$1=="static_conn") printf "%s %s %s %s %s %s\n",$$2,$$3,$$5,$$6,$$4,$$7}'|sort|./sort_seq -|./merge_seq -|awk '{printf "%s %s %s %s %s %s\n",$$1,$$2,$$5,$$3,$$4,$$6}'|sort >$@
|
||||
@cat $<|awk '{if ($$1=="conn") printf "%s %s %s %s %s %s\n",$$2,$$3,$$5,$$6,$$4,$$7}'|sort|./sort_seq -|./merge_seq -|awk '{printf "%s %s %s %s %s %s\n",$$1,$$2,$$5,$$3,$$4,$$6}'|sort >$@
|
||||
|
||||
%.ports: %.fp
|
||||
@cat $<|awk '{if ($$1=="port") printf "%s %s %s\n",$$2,$$3,$$4}'|sort >$@
|
||||
|
||||
%.sw: %.fp
|
||||
@cat $<|awk '{if ($$1=="switch") printf "%s %s %s %s %s\n",$$2,$$3,$$4,$$5,$$6}'|sort >$@
|
||||
@cat $<|awk '{if ($$1=="sw") printf "%s %s %s %s %s\n",$$2,$$3,$$4,$$5,$$6}'|sort >$@
|
||||
|
||||
clean:
|
||||
rm -f bit2txt bit2txt.o \
|
||||
|
@ -122,12 +122,12 @@ clean:
|
|||
merge_seq merge_seq.o \
|
||||
autotest.o control.o floorplan.o \
|
||||
xc6slx9_empty.fp xc6slx9.svg \
|
||||
xc6slx9_empty.tiles xc6slx9_empty.devices xc6slx9_empty.conns \
|
||||
xc6slx9_empty.tiles xc6slx9_empty.devs xc6slx9_empty.conns \
|
||||
xc6slx9_empty.ports xc6slx9_empty.sw xc6slx9_empty.nets \
|
||||
compare_other.tiles compare_other.devices compare_other.conns compare_other.ports \
|
||||
compare_other.tiles compare_other.devs compare_other.conns compare_other.ports \
|
||||
compare_other.sw compare_other.nets \
|
||||
compare_tiles_matching.txt compare_tiles_diff.txt compare_tiles_extra.txt \
|
||||
compare_devices_matching.txt compare_devices_diff.txt compare_devices_extra.txt \
|
||||
compare_devs_matching.txt compare_devs_diff.txt compare_devs_extra.txt \
|
||||
compare_conns_matching.txt compare_conns_diff.txt compare_conns_extra.txt \
|
||||
compare_ports_matching.txt compare_ports_diff.txt compare_ports_extra.txt \
|
||||
compare_sw_matching.txt compare_sw_diff.txt compare_sw_extra.txt \
|
||||
|
|
20
autotest.c
20
autotest.c
|
@ -63,17 +63,29 @@ int main(int argc, char** argv)
|
|||
printf("O Done\n");
|
||||
TIME_AND_MEM();
|
||||
|
||||
// todo: pick 2 input IOBs, one output IOB and configure them
|
||||
// todo: pick 1 logic block and configure
|
||||
// configure P46
|
||||
rc = fpga_find_iob(&model, "P46", &iob_y, &iob_x, &iob_idx);
|
||||
EXIT(rc);
|
||||
|
||||
dev = fpga_dev(&model, iob_y, iob_x, DEV_IOB, iob_idx);
|
||||
EXIT(!dev);
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.istandard, IO_LVCMOS33);
|
||||
dev->iob.bypass_mux = BYPASS_MUX_I;
|
||||
dev->iob.imux = IMUX_I;
|
||||
dev->iob.I_mux = IMUX_I;
|
||||
|
||||
// configure P48
|
||||
rc = fpga_find_iob(&model, "P48", &iob_y, &iob_x, &iob_idx);
|
||||
EXIT(rc);
|
||||
dev = fpga_dev(&model, iob_y, iob_x, DEV_IOB, iob_idx);
|
||||
EXIT(!dev);
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.ostandard, IO_LVCMOS33);
|
||||
dev->iob.drive_strength = 12;
|
||||
dev->iob.O_used = 1;
|
||||
dev->iob.slew = SLEW_SLOW;
|
||||
dev->iob.suspend = SUSP_3STATE;
|
||||
|
||||
// todo: configure logic
|
||||
|
||||
mkdir(AUTOTEST_TMP_DIR, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH);
|
||||
dest_f = fopen(AUTOTEST_TMP_DIR "/test_0001.fp", "w");
|
||||
|
|
|
@ -164,10 +164,10 @@ struct fpga_device* fpga_dev(struct fpga_model* model,
|
|||
|
||||
tile = YX_TILE(model, y, x);
|
||||
type_count = 0;
|
||||
for (i = 0; i < tile->num_devices; i++) {
|
||||
if (tile->devices[i].type == type) {
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
if (tile->devs[i].type == type) {
|
||||
if (type_count == idx)
|
||||
return &tile->devices[i];
|
||||
return &tile->devs[i];
|
||||
type_count++;
|
||||
}
|
||||
}
|
||||
|
|
269
floorplan.c
269
floorplan.c
|
@ -5,6 +5,8 @@
|
|||
// For details see the UNLICENSE file at the root of the source tree.
|
||||
//
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "model.h"
|
||||
#include "floorplan.h"
|
||||
|
||||
|
@ -57,105 +59,288 @@ int printf_tiles(FILE* f, struct fpga_model* model)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void printf_wrap(FILE* f, char* line, int prefix_len,
|
||||
const char* fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
int i;
|
||||
|
||||
va_start(list, fmt);
|
||||
i = strlen(line);
|
||||
if (i >= 80) {
|
||||
line[i] = '\n';
|
||||
line[i+1] = 0;
|
||||
fprintf(f, line);
|
||||
line[prefix_len] = 0;
|
||||
i = prefix_len;
|
||||
}
|
||||
line[i] = ' ';
|
||||
vsnprintf(&line[i+1], 256, fmt, list);
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
static int printf_IOB(FILE* f, struct fpga_model* model,
|
||||
int y, int x, int config_only)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
char line[1024];
|
||||
int type_count, plen, i;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
type_count = 0;
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
if (tile->devs[i].type != DEV_IOB)
|
||||
continue;
|
||||
if (config_only && !(tile->devs[i].instantiated)) {
|
||||
type_count++;
|
||||
continue;
|
||||
}
|
||||
snprintf(line, sizeof(line), "dev y%02i x%02i IOB %i",
|
||||
y, x, type_count);
|
||||
type_count++;
|
||||
plen = strlen(line);
|
||||
|
||||
printf_wrap(f, line, plen, "type %s",
|
||||
tile->devs[i].iob.subtype == IOBM
|
||||
? "M" : "S");
|
||||
if (tile->devs[i].iob.istandard[0])
|
||||
printf_wrap(f, line, plen, "istd %s",
|
||||
tile->devs[i].iob.istandard);
|
||||
if (tile->devs[i].iob.ostandard[0])
|
||||
printf_wrap(f, line, plen, "ostd %s",
|
||||
tile->devs[i].iob.ostandard);
|
||||
switch (tile->devs[i].iob.bypass_mux) {
|
||||
case BYPASS_MUX_I:
|
||||
printf_wrap(f, line, plen, "bypass_mux I");
|
||||
break;
|
||||
case BYPASS_MUX_O:
|
||||
printf_wrap(f, line, plen, "bypass_mux O");
|
||||
break;
|
||||
case BYPASS_MUX_T:
|
||||
printf_wrap(f, line, plen, "bypass_mux T");
|
||||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
switch (tile->devs[i].iob.I_mux) {
|
||||
case IMUX_I_B:
|
||||
printf_wrap(f, line, plen, "imux I_B");
|
||||
break;
|
||||
case IMUX_I:
|
||||
printf_wrap(f, line, plen, "imux I");
|
||||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
if (tile->devs[i].iob.drive_strength)
|
||||
printf_wrap(f, line, plen, "strength %i",
|
||||
tile->devs[i].iob.drive_strength);
|
||||
switch (tile->devs[i].iob.slew) {
|
||||
case SLEW_SLOW:
|
||||
printf_wrap(f, line, plen, "slew SLOW");
|
||||
break;
|
||||
case SLEW_FAST:
|
||||
printf_wrap(f, line, plen, "slew FAST");
|
||||
break;
|
||||
case SLEW_QUIETIO:
|
||||
printf_wrap(f, line, plen, "slew QUIETIO");
|
||||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
if (tile->devs[i].iob.O_used)
|
||||
printf_wrap(f, line, plen, "o_used");
|
||||
switch (tile->devs[i].iob.suspend) {
|
||||
case SUSP_LAST_VAL:
|
||||
printf_wrap(f, line, plen, "suspend DRIVE_LAST_VALUE");
|
||||
break;
|
||||
case SUSP_3STATE:
|
||||
printf_wrap(f, line, plen, "suspend 3STATE");
|
||||
break;
|
||||
case SUSP_3STATE_PULLUP:
|
||||
printf_wrap(f, line, plen, "suspend 3STATE_PULLUP");
|
||||
break;
|
||||
case SUSP_3STATE_PULLDOWN:
|
||||
printf_wrap(f, line, plen, "suspend 3STATE_PULLDOWN");
|
||||
break;
|
||||
case SUSP_3STATE_KEEPER:
|
||||
printf_wrap(f, line, plen, "suspend 3STATE_KEEPER");
|
||||
break;
|
||||
case SUSP_3STATE_OCT_ON:
|
||||
printf_wrap(f, line, plen, "suspend 3STATE_OCT_ON");
|
||||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
switch (tile->devs[i].iob.in_term) {
|
||||
case ITERM_NONE:
|
||||
printf_wrap(f, line, plen, "in_term NONE");
|
||||
break;
|
||||
case ITERM_UNTUNED_25:
|
||||
printf_wrap(f, line, plen, "in_term UNTUNED_SPLIT_25");
|
||||
break;
|
||||
case ITERM_UNTUNED_50:
|
||||
printf_wrap(f, line, plen, "in_term UNTUNED_SPLIT_50");
|
||||
break;
|
||||
case ITERM_UNTUNED_75:
|
||||
printf_wrap(f, line, plen, "in_term UNTUNED_SPLIT_75");
|
||||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
switch (tile->devs[i].iob.out_term) {
|
||||
case OTERM_NONE:
|
||||
printf_wrap(f, line, plen, "out_term NONE");
|
||||
break;
|
||||
case OTERM_UNTUNED_25:
|
||||
printf_wrap(f, line, plen, "out_term UNTUNED_25");
|
||||
break;
|
||||
case OTERM_UNTUNED_50:
|
||||
printf_wrap(f, line, plen, "out_term UNTUNED_50");
|
||||
break;
|
||||
case OTERM_UNTUNED_75:
|
||||
printf_wrap(f, line, plen, "out_term UNTUNED_75");
|
||||
break;
|
||||
case 0: break; default: EXIT(1);
|
||||
}
|
||||
strcat(line, "\n");
|
||||
fprintf(f, line);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int printf_LOGIC(FILE* f, struct fpga_model* model,
|
||||
int y, int x, int config_only)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
char line[1024];
|
||||
int type_count, plen, i;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
type_count = 0;
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
if (tile->devs[i].type != DEV_LOGIC)
|
||||
continue;
|
||||
if (config_only && !(tile->devs[i].instantiated)) {
|
||||
type_count++;
|
||||
continue;
|
||||
}
|
||||
snprintf(line, sizeof(line), "dev y%02i x%02i LOGIC %i",
|
||||
y, x, type_count);
|
||||
type_count++;
|
||||
plen = strlen(line);
|
||||
|
||||
switch (tile->devs[i].logic.subtype) {
|
||||
case LOGIC_X:
|
||||
printf_wrap(f, line, plen, "type X");
|
||||
break;
|
||||
case LOGIC_L:
|
||||
printf_wrap(f, line, plen, "type L");
|
||||
break;
|
||||
case LOGIC_M:
|
||||
printf_wrap(f, line, plen, "type M");
|
||||
break;
|
||||
default: EXIT(1);
|
||||
}
|
||||
strcat(line, "\n");
|
||||
fprintf(f, line);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printf_devices(FILE* f, struct fpga_model* model, int config_only)
|
||||
{
|
||||
int x, y, i;
|
||||
int x, y, i, rc;
|
||||
struct fpga_tile* tile;
|
||||
|
||||
for (x = 0; x < model->x_width; x++) {
|
||||
for (y = 0; y < model->y_height; y++) {
|
||||
|
||||
rc = printf_IOB(f, model, y, x, config_only);
|
||||
if (rc) goto fail;
|
||||
rc = printf_LOGIC(f, model, y, x, config_only);
|
||||
if (rc) goto fail;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
for (i = 0; i < tile->num_devices; i++) {
|
||||
if (config_only && !(tile->devices[i].instantiated))
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
if (config_only && !(tile->devs[i].instantiated))
|
||||
continue;
|
||||
switch (tile->devices[i].type) {
|
||||
case DEV_LOGIC_M:
|
||||
fprintf(f, "device y%02i x%02i SLICEM\n", y, x);
|
||||
break;
|
||||
case DEV_LOGIC_L:
|
||||
fprintf(f, "device y%02i x%02i SLICEL\n", y, x);
|
||||
break;
|
||||
case DEV_LOGIC_X:
|
||||
fprintf(f, "device y%02i x%02i SLICEX\n", y, x);
|
||||
break;
|
||||
switch (tile->devs[i].type) {
|
||||
case DEV_MACC:
|
||||
fprintf(f, "device y%02i x%02i DSP48A1\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i DSP48A1\n", y, x);
|
||||
break;
|
||||
case DEV_TIEOFF:
|
||||
fprintf(f, "device y%02i x%02i TIEOFF\n", y, x);
|
||||
break;
|
||||
case DEV_IOB:
|
||||
fprintf(f, "device y%02i x%02i %s\n", y, x,
|
||||
tile->devices[i].iob.type == IOBM ? "IOBM" : "IOBS");
|
||||
fprintf(f, "dev y%02i x%02i TIEOFF\n", y, x);
|
||||
break;
|
||||
case DEV_ILOGIC:
|
||||
fprintf(f, "device y%02i x%02i ILOGIC2\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i ILOGIC\n", y, x);
|
||||
break;
|
||||
case DEV_OLOGIC:
|
||||
fprintf(f, "device y%02i x%02i OLOGIC2\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i OLOGIC\n", y, x);
|
||||
break;
|
||||
case DEV_IODELAY:
|
||||
fprintf(f, "device y%02i x%02i IODELAY2\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i IODELAY\n", y, x);
|
||||
break;
|
||||
case DEV_BRAM16:
|
||||
fprintf(f, "device y%02i x%02i RAMB16BWER\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i RAMB16\n", y, x);
|
||||
break;
|
||||
case DEV_BRAM8:
|
||||
fprintf(f, "device y%02i x%02i RAMB8BWER\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i RAMB8\n", y, x);
|
||||
break;
|
||||
case DEV_BUFH:
|
||||
fprintf(f, "device y%02i x%02i BUFH\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i BUFH\n", y, x);
|
||||
break;
|
||||
case DEV_BUFIO:
|
||||
fprintf(f, "device y%02i x%02i BUFIO2\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i BUFIO2\n", y, x);
|
||||
break;
|
||||
case DEV_BUFIO_FB:
|
||||
fprintf(f, "device y%02i x%02i BUFIO2FB\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i BUFIO2FB\n", y, x);
|
||||
break;
|
||||
case DEV_BUFPLL:
|
||||
fprintf(f, "device y%02i x%02i BUFPLL\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i BUFPLL\n", y, x);
|
||||
break;
|
||||
case DEV_BUFPLL_MCB:
|
||||
fprintf(f, "device y%02i x%02i BUFPLL_MCB\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i BUFPLL_MCB\n", y, x);
|
||||
break;
|
||||
case DEV_BUFGMUX:
|
||||
fprintf(f, "device y%02i x%02i BUFGMUX\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i BUFGMUX\n", y, x);
|
||||
break;
|
||||
case DEV_BSCAN:
|
||||
fprintf(f, "device y%02i x%02i BSCAN\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i BSCAN\n", y, x);
|
||||
break;
|
||||
case DEV_DCM:
|
||||
fprintf(f, "device y%02i x%02i DCM\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i DCM\n", y, x);
|
||||
break;
|
||||
case DEV_PLL:
|
||||
fprintf(f, "device y%02i x%02i PLL_ADV\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i PLL\n", y, x);
|
||||
break;
|
||||
case DEV_ICAP:
|
||||
fprintf(f, "device y%02i x%02i ICAP\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i ICAP\n", y, x);
|
||||
break;
|
||||
case DEV_POST_CRC_INTERNAL:
|
||||
fprintf(f, "device y%02i x%02i POST_CRC_INTERNAL\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i POST_CRC_INTERNAL\n", y, x);
|
||||
break;
|
||||
case DEV_STARTUP:
|
||||
fprintf(f, "device y%02i x%02i STARTUP\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i STARTUP\n", y, x);
|
||||
break;
|
||||
case DEV_SLAVE_SPI:
|
||||
fprintf(f, "device y%02i x%02i SLAVE_SPI\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i SLAVE_SPI\n", y, x);
|
||||
break;
|
||||
case DEV_SUSPEND_SYNC:
|
||||
fprintf(f, "device y%02i x%02i SUSPEND_SYNC\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i SUSPEND_SYNC\n", y, x);
|
||||
break;
|
||||
case DEV_OCT_CALIBRATE:
|
||||
fprintf(f, "device y%02i x%02i OCT_CALIBRATE\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i OCT_CALIBRATE\n", y, x);
|
||||
break;
|
||||
case DEV_SPI_ACCESS:
|
||||
fprintf(f, "device y%02i x%02i SPI_ACCESS\n", y, x);
|
||||
fprintf(f, "dev y%02i x%02i SPI_ACCESS\n", y, x);
|
||||
break;
|
||||
case DEV_IOB:
|
||||
case DEV_LOGIC:
|
||||
// to suppress compiler warning
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int printf_ports(FILE* f, struct fpga_model* model)
|
||||
|
@ -241,7 +426,7 @@ int printf_conns(FILE* f, struct fpga_model* model)
|
|||
first_conn_printed = 1;
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
sprintf(tmp_line, "static_conn y%02i x%02i %s ",
|
||||
sprintf(tmp_line, "conn y%02i x%02i %s ",
|
||||
y, x, conn_point_name_src);
|
||||
k = strlen(tmp_line);
|
||||
while (k < 45)
|
||||
|
@ -290,7 +475,7 @@ int printf_switches(FILE* f, struct fpga_model* model, int enabled_only)
|
|||
first_switch_printed = 1;
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fprintf(f, "switch y%02i x%02i %s %s %s\n",
|
||||
fprintf(f, "sw y%02i x%02i %s %s %s\n",
|
||||
y, x, from_str, is_bidirectional
|
||||
? "<->" : "->", to_str);
|
||||
}
|
||||
|
|
38
model.h
38
model.h
|
@ -271,9 +271,7 @@ const char* logicin_s(int wire, int routing_io);
|
|||
|
||||
enum fpgadev_type
|
||||
{
|
||||
DEV_LOGIC_M,
|
||||
DEV_LOGIC_L,
|
||||
DEV_LOGIC_X,
|
||||
DEV_LOGIC,
|
||||
DEV_TIEOFF,
|
||||
DEV_MACC,
|
||||
DEV_IOB,
|
||||
|
@ -304,19 +302,13 @@ enum fpgadev_type
|
|||
// 0 is never a valid configured setting. That way all config
|
||||
// data can safely be initialized to 0 meaning unconfigured.
|
||||
|
||||
struct fpgadev_logic_x
|
||||
{
|
||||
int a;
|
||||
};
|
||||
enum { LOGIC_M = 1, LOGIC_L, LOGIC_X };
|
||||
|
||||
struct fpgadev_logic_l
|
||||
struct fpgadev_logic
|
||||
{
|
||||
int b;
|
||||
};
|
||||
|
||||
struct fpgadev_logic_m
|
||||
{
|
||||
int c;
|
||||
int subtype; // LOGIC_M, LOGIC_L or LOGIC_X
|
||||
int A_used, B_used, C_used, D_used;
|
||||
char* A6_lut, *B6_lut, *C6_lut, *D6_lut;
|
||||
};
|
||||
|
||||
enum { IOBM = 1, IOBS };
|
||||
|
@ -334,14 +326,14 @@ enum { OTERM_NONE = 1, OTERM_UNTUNED_25, OTERM_UNTUNED_50,
|
|||
|
||||
struct fpgadev_iob
|
||||
{
|
||||
int type;
|
||||
int subtype; // IOBM or IOBS
|
||||
IOSTANDARD istandard;
|
||||
IOSTANDARD ostandard;
|
||||
int bypass_mux;
|
||||
int imux;
|
||||
int I_mux;
|
||||
int drive_strength; // supports 2,4,6,8,12,16 and 24
|
||||
int slew;
|
||||
int o_used;
|
||||
int O_used;
|
||||
int suspend;
|
||||
int in_term;
|
||||
int out_term;
|
||||
|
@ -352,9 +344,7 @@ struct fpga_device
|
|||
enum fpgadev_type type;
|
||||
int instantiated;
|
||||
union {
|
||||
struct fpgadev_logic_m log_m;
|
||||
struct fpgadev_logic_l log_l;
|
||||
struct fpgadev_logic_x log_x;
|
||||
struct fpgadev_logic logic;
|
||||
struct fpgadev_iob iob;
|
||||
};
|
||||
};
|
||||
|
@ -368,9 +358,9 @@ struct fpga_tile
|
|||
enum fpga_tile_type type;
|
||||
int flags;
|
||||
|
||||
// we currently support a maximum of 32 devices per tile
|
||||
int num_devices;
|
||||
struct fpga_device devices[32];
|
||||
// expect up to 64 devices per tile
|
||||
int num_devs;
|
||||
struct fpga_device* devs;
|
||||
|
||||
// expect up to 5k connection point names per tile
|
||||
// 2*16 bit per entry
|
||||
|
@ -407,6 +397,7 @@ 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);
|
||||
|
||||
const char* pf(const char* fmt, ...);
|
||||
|
@ -417,6 +408,7 @@ 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 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);
|
||||
|
||||
|
|
|
@ -61,9 +61,9 @@ static int connect_logic_carry(struct fpga_model* model)
|
|||
for (x = 0; x < model->x_width; x++) {
|
||||
if (is_atx(X_LOGIC_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (has_device(model, y, x, DEV_LOGIC_M)) {
|
||||
if (has_device_type(model, y, x, DEV_LOGIC, LOGIC_M)) {
|
||||
if (is_aty(Y_CHIP_HORIZ_REGS, model, y-1)
|
||||
&& has_device(model, y-2, x, DEV_LOGIC_M)) {
|
||||
&& has_device_type(model, y-2, x, DEV_LOGIC, LOGIC_M)) {
|
||||
struct w_net net = {
|
||||
0,
|
||||
{{ "M_CIN", 0, y-2, x },
|
||||
|
@ -72,7 +72,7 @@ static int connect_logic_carry(struct fpga_model* model)
|
|||
{ "" }}};
|
||||
if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout;
|
||||
} else if (is_aty(Y_ROW_HORIZ_AXSYMM, model, y-1)
|
||||
&& has_device(model, y-2, x, DEV_LOGIC_M)) {
|
||||
&& has_device_type(model, y-2, x, DEV_LOGIC, LOGIC_M)) {
|
||||
struct w_net net = {
|
||||
0,
|
||||
{{ "M_CIN", 0, y-2, x },
|
||||
|
@ -80,7 +80,7 @@ static int connect_logic_carry(struct fpga_model* model)
|
|||
{ "M_COUT_N", 0, y, x },
|
||||
{ "" }}};
|
||||
if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout;
|
||||
} else if (has_device(model, y-1, x, DEV_LOGIC_M)) {
|
||||
} else if (has_device_type(model, y-1, x, DEV_LOGIC, LOGIC_M)) {
|
||||
if ((rc = add_conn_bi(model, y, x, "M_COUT_N", y-1, x, "M_CIN"))) goto xout;
|
||||
}
|
||||
}
|
||||
|
@ -120,13 +120,13 @@ static int connect_clk_sr(struct fpga_model* model, const char* clk_sr)
|
|||
}
|
||||
if (is_atx(X_FABRIC_LOGIC_ROUTING_COL|X_CENTER_ROUTING_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (has_device(model, y, x+1, DEV_LOGIC_M)) {
|
||||
if (has_device_type(model, y, x+1, DEV_LOGIC, LOGIC_M)) {
|
||||
if ((rc = add_conn_range(model,
|
||||
NOPREF_BI_F,
|
||||
y, x, pf("%s%%i", clk_sr), 0, 1,
|
||||
y, x+1, pf("CLEXM_%s%%i", clk_sr), 0)))
|
||||
goto xout;
|
||||
} else if (has_device(model, y, x+1, DEV_LOGIC_L)) {
|
||||
} else if (has_device_type(model, y, x+1, DEV_LOGIC, LOGIC_L)) {
|
||||
if ((rc = add_conn_range(model,
|
||||
NOPREF_BI_F,
|
||||
y, x, pf("%s%%i", clk_sr), 0, 1,
|
||||
|
|
378
model_devices.c
378
model_devices.c
|
@ -8,241 +8,297 @@
|
|||
#include <stdarg.h>
|
||||
#include "model.h"
|
||||
|
||||
void free_devices(struct fpga_model* model)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < model->x_width * model->y_height; i++) {
|
||||
if (!model->tiles[i].num_devs)
|
||||
continue;
|
||||
EXIT(!model->tiles[i].devs);
|
||||
for (j = 0; j < model->tiles[i].num_devs; j++) {
|
||||
if (model->tiles[i].devs[j].type != DEV_LOGIC)
|
||||
continue;
|
||||
free(model->tiles[i].devs[i].logic.A6_lut);
|
||||
model->tiles[i].devs[i].logic.A6_lut = 0;
|
||||
free(model->tiles[i].devs[i].logic.B6_lut);
|
||||
model->tiles[i].devs[i].logic.B6_lut = 0;
|
||||
free(model->tiles[i].devs[i].logic.C6_lut);
|
||||
model->tiles[i].devs[i].logic.C6_lut = 0;
|
||||
free(model->tiles[i].devs[i].logic.D6_lut);
|
||||
model->tiles[i].devs[i].logic.D6_lut = 0;
|
||||
}
|
||||
free(model->tiles[i].devs);
|
||||
model->tiles[i].devs = 0;
|
||||
model->tiles[i].num_devs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define DEV_INCREMENT 8
|
||||
|
||||
static int add_dev(struct fpga_model* model,
|
||||
int y, int x, int type, int subtype)
|
||||
{
|
||||
struct fpga_tile* tile = YX_TILE(model, y, x);
|
||||
if (!(tile->num_devs % DEV_INCREMENT)) {
|
||||
void* new_ptr = realloc(tile->devs,
|
||||
(tile->num_devs+DEV_INCREMENT)*sizeof(*tile->devs));
|
||||
EXIT(!new_ptr);
|
||||
memset(new_ptr + tile->num_devs * sizeof(*tile->devs), 0, DEV_INCREMENT*sizeof(*tile->devs));
|
||||
tile->devs = new_ptr;
|
||||
}
|
||||
tile->devs[tile->num_devs].type = type;
|
||||
if (type == DEV_IOB)
|
||||
tile->devs[tile->num_devs].iob.subtype = subtype;
|
||||
else if (type == DEV_LOGIC)
|
||||
tile->devs[tile->num_devs].logic.subtype = subtype;
|
||||
tile->num_devs++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_devices(struct fpga_model* model)
|
||||
{
|
||||
int x, y, i, j;
|
||||
struct fpga_tile* tile;
|
||||
int x, y, i, j, rc;
|
||||
|
||||
// DCM, PLL_ADV
|
||||
// DCM, PLL
|
||||
for (i = 0; i < model->cfg_rows; i++) {
|
||||
y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
|
||||
y = TOP_IO_TILES + HALF_ROW-1 + i*ROW_SIZE;
|
||||
if (y > model->center_y) y++; // central regs
|
||||
tile = YX_TILE(model, y-1, model->center_x-CENTER_CMTPLL_O);
|
||||
x = model->center_x-CENTER_CMTPLL_O;
|
||||
if (i%2) {
|
||||
tile->devices[tile->num_devices++].type = DEV_DCM;
|
||||
tile->devices[tile->num_devices++].type = DEV_DCM;
|
||||
if ((rc = add_dev(model, y, x, DEV_DCM, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_DCM, 0))) goto fail;
|
||||
} else
|
||||
tile->devices[tile->num_devices++].type = DEV_PLL;
|
||||
if ((rc = add_dev(model, y, x, DEV_PLL, 0))) goto fail;
|
||||
}
|
||||
|
||||
// BSCAN
|
||||
tile = YX_TILE(model, TOP_IO_TILES, model->x_width-RIGHT_IO_DEVS_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_BSCAN;
|
||||
tile->devices[tile->num_devices++].type = DEV_BSCAN;
|
||||
y = TOP_IO_TILES;
|
||||
x = model->x_width-RIGHT_IO_DEVS_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_BSCAN, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BSCAN, 0))) goto fail;
|
||||
|
||||
// BSCAN, OCT_CALIBRATE
|
||||
tile = YX_TILE(model, TOP_IO_TILES+1, model->x_width-RIGHT_IO_DEVS_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_BSCAN;
|
||||
tile->devices[tile->num_devices++].type = DEV_BSCAN;
|
||||
tile->devices[tile->num_devices++].type = DEV_OCT_CALIBRATE;
|
||||
y = TOP_IO_TILES+1;
|
||||
x = model->x_width-RIGHT_IO_DEVS_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_BSCAN, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BSCAN, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_OCT_CALIBRATE, 0))) goto fail;
|
||||
|
||||
// ICAP, SPI_ACCESS, OCT_CALIBRATE
|
||||
tile = YX_TILE(model, model->y_height-BOT_IO_TILES-1,
|
||||
model->x_width-RIGHT_IO_DEVS_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_ICAP;
|
||||
tile->devices[tile->num_devices++].type = DEV_SPI_ACCESS;
|
||||
tile->devices[tile->num_devices++].type = DEV_OCT_CALIBRATE;
|
||||
y = model->y_height-BOT_IO_TILES-1;
|
||||
x = model->x_width-RIGHT_IO_DEVS_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_ICAP, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_SPI_ACCESS, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_OCT_CALIBRATE, 0))) goto fail;
|
||||
|
||||
// STARTUP, POST_CRC_INTERNAL, SLAVE_SPI, SUSPEND_SYNC
|
||||
tile = YX_TILE(model, model->y_height-BOT_IO_TILES-2,
|
||||
model->x_width-RIGHT_IO_DEVS_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_STARTUP;
|
||||
tile->devices[tile->num_devices++].type = DEV_POST_CRC_INTERNAL;
|
||||
tile->devices[tile->num_devices++].type = DEV_SLAVE_SPI;
|
||||
tile->devices[tile->num_devices++].type = DEV_SUSPEND_SYNC;
|
||||
y = model->y_height-BOT_IO_TILES-2;
|
||||
x = model->x_width-RIGHT_IO_DEVS_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_STARTUP, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_POST_CRC_INTERNAL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_SLAVE_SPI, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_SUSPEND_SYNC, 0))) goto fail;
|
||||
|
||||
// BUFGMUX
|
||||
tile = YX_TILE(model, model->center_y, model->center_x);
|
||||
y = model->center_y;
|
||||
x = model->center_x;
|
||||
for (i = 0; i < 16; i++)
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFGMUX;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFGMUX, 0))) goto fail;
|
||||
|
||||
// BUFIO, BUFIO_FB, BUFPLL, BUFPLL_MCB
|
||||
tile = YX_TILE(model, TOP_OUTER_ROW, model->center_x-CENTER_CMTPLL_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB;
|
||||
y = TOP_OUTER_ROW;
|
||||
x = model->center_x-CENTER_CMTPLL_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL_MCB, 0))) goto fail;
|
||||
for (j = 0; j < 8; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO_FB;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO_FB, 0))) goto fail;
|
||||
}
|
||||
tile = YX_TILE(model, model->center_y, LEFT_OUTER_COL);
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB;
|
||||
y = model->center_y;
|
||||
x = LEFT_OUTER_COL;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL_MCB, 0))) goto fail;
|
||||
for (j = 0; j < 8; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO_FB;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO_FB, 0))) goto fail;
|
||||
}
|
||||
tile = YX_TILE(model, model->center_y, model->x_width - RIGHT_OUTER_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB;
|
||||
y = model->center_y;
|
||||
x = model->x_width - RIGHT_OUTER_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL_MCB, 0))) goto fail;
|
||||
for (j = 0; j < 8; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO_FB;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO_FB, 0))) goto fail;
|
||||
}
|
||||
tile = YX_TILE(model, model->y_height - BOT_OUTER_ROW, model->center_x-CENTER_CMTPLL_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB;
|
||||
y = model->y_height - BOT_OUTER_ROW;
|
||||
x = model->center_x-CENTER_CMTPLL_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFPLL_MCB, 0))) goto fail;
|
||||
for (j = 0; j < 8; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO;
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFIO_FB;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO, 0))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFIO_FB, 0))) goto fail;
|
||||
}
|
||||
|
||||
// BUFH
|
||||
for (i = 0; i < model->cfg_rows; i++) {
|
||||
y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
|
||||
if (y > model->center_y) y++; // central regs
|
||||
tile = YX_TILE(model, y, model->center_x);
|
||||
x = model->center_x;
|
||||
for (j = 0; j < 32; j++)
|
||||
tile->devices[tile->num_devices++].type = DEV_BUFH;
|
||||
if ((rc = add_dev(model, y, x, DEV_BUFH, 0))) goto fail;
|
||||
}
|
||||
|
||||
// BRAM
|
||||
for (x = 0; x < model->x_width; x++) {
|
||||
if (is_atx(X_FABRIC_BRAM_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
if (tile->flags & TF_BRAM_DEV) {
|
||||
tile->devices[tile->num_devices++].type = DEV_BRAM16;
|
||||
tile->devices[tile->num_devices++].type = DEV_BRAM8;
|
||||
tile->devices[tile->num_devices++].type = DEV_BRAM8;
|
||||
}
|
||||
}
|
||||
if (!is_atx(X_FABRIC_BRAM_COL, model, x))
|
||||
continue;
|
||||
for (y = TOP_IO_TILES; y < model->y_height-BOT_IO_TILES; y++) {
|
||||
if (!(YX_TILE(model, y, x)->flags & TF_BRAM_DEV))
|
||||
continue;
|
||||
if ((rc = add_dev(model, y, x, DEV_BRAM16, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BRAM8, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_BRAM8, 0)))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
// MACC
|
||||
for (x = 0; x < model->x_width; x++) {
|
||||
if (is_atx(X_FABRIC_MACC_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
if (tile->flags & TF_MACC_DEV)
|
||||
tile->devices[tile->num_devices++].type = DEV_MACC;
|
||||
}
|
||||
if (!is_atx(X_FABRIC_MACC_COL, model, x))
|
||||
continue;
|
||||
for (y = TOP_IO_TILES; y < model->y_height-BOT_IO_TILES; y++) {
|
||||
if (!(YX_TILE(model, y, x)->flags & TF_MACC_DEV))
|
||||
continue;
|
||||
if ((rc = add_dev(model, y, x, DEV_MACC, 0))) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
// ILOGIC/OLOGIC/IODELAY
|
||||
for (x = LEFT_SIDE_WIDTH; x < model->x_width - RIGHT_SIDE_WIDTH; x++) {
|
||||
if (is_atx(X_LOGIC_COL, model, x)
|
||||
&& !is_atx(X_ROUTING_NO_IO, model, x-1)) {
|
||||
for (i = 0; i <= 1; i++) {
|
||||
tile = YX_TILE(model, TOP_IO_TILES+i, x);
|
||||
for (j = 0; j <= 1; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_ILOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_OLOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_IODELAY;
|
||||
}
|
||||
tile = YX_TILE(model, model->y_height-BOT_IO_TILES-i-1, x);
|
||||
for (j = 0; j <= 1; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_ILOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_OLOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_IODELAY;
|
||||
}
|
||||
if (!is_atx(X_LOGIC_COL, model, x)
|
||||
|| is_atx(X_ROUTING_NO_IO, model, x-1))
|
||||
continue;
|
||||
for (i = 0; i <= 1; i++) {
|
||||
y = TOP_IO_TILES+i;
|
||||
for (j = 0; j <= 1; j++) {
|
||||
if ((rc = add_dev(model, y, x, DEV_ILOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_OLOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IODELAY, 0)))
|
||||
goto fail;
|
||||
}
|
||||
y = model->y_height-BOT_IO_TILES-i-1;
|
||||
for (j = 0; j <= 1; j++) {
|
||||
if ((rc = add_dev(model, y, x, DEV_ILOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_OLOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IODELAY, 0)))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (is_aty(Y_LEFT_WIRED, model, y)) {
|
||||
tile = YX_TILE(model, y, LEFT_IO_DEVS);
|
||||
x = LEFT_IO_DEVS;
|
||||
for (j = 0; j <= 1; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_ILOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_OLOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_IODELAY;
|
||||
if ((rc = add_dev(model, y, x, DEV_ILOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_OLOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IODELAY, 0)))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (is_aty(Y_RIGHT_WIRED, model, y)) {
|
||||
tile = YX_TILE(model, y, model->x_width-RIGHT_IO_DEVS_O);
|
||||
x = model->x_width-RIGHT_IO_DEVS_O;
|
||||
for (j = 0; j <= 1; j++) {
|
||||
tile->devices[tile->num_devices++].type = DEV_ILOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_OLOGIC;
|
||||
tile->devices[tile->num_devices++].type = DEV_IODELAY;
|
||||
if ((rc = add_dev(model, y, x, DEV_ILOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_OLOGIC, 0)))
|
||||
goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IODELAY, 0)))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IOB
|
||||
for (x = 0; x < model->x_width; x++) {
|
||||
// Note that the order of sub-types IOBM and IOBS must match
|
||||
// the order in the control.c sitename arrays.
|
||||
if (is_atx(X_OUTER_LEFT, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (is_aty(Y_LEFT_WIRED, model, y)) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBM;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBS;
|
||||
}
|
||||
if (!is_aty(Y_LEFT_WIRED, model, y))
|
||||
continue;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
}
|
||||
}
|
||||
if (is_atx(X_OUTER_RIGHT, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (is_aty(Y_RIGHT_WIRED, model, y)) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBM;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBS;
|
||||
}
|
||||
if (!is_aty(Y_RIGHT_WIRED, model, y))
|
||||
continue;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
}
|
||||
}
|
||||
if (is_atx(X_FABRIC_LOGIC_ROUTING_COL|X_CENTER_ROUTING_COL, model, x)
|
||||
&& !is_atx(X_ROUTING_NO_IO, model, x)) {
|
||||
tile = YX_TILE(model, TOP_OUTER_ROW, x);
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBM;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBS;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBM;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBS;
|
||||
y = TOP_OUTER_ROW;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
|
||||
tile = YX_TILE(model, model->y_height-BOT_OUTER_ROW, x);
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBM;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBS;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBM;
|
||||
tile->devices[tile->num_devices].type = DEV_IOB;
|
||||
tile->devices[tile->num_devices++].iob.type = IOBS;
|
||||
y = model->y_height-BOT_OUTER_ROW;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
// TIEOFF
|
||||
tile = YX_TILE(model, model->center_y, LEFT_OUTER_COL);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
tile = YX_TILE(model, model->center_y, model->x_width-RIGHT_OUTER_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
tile = YX_TILE(model, TOP_OUTER_ROW, model->center_x-1);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
tile = YX_TILE(model, model->y_height-BOT_OUTER_ROW, model->center_x-CENTER_CMTPLL_O);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
y = model->center_y;
|
||||
x = LEFT_OUTER_COL;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
y = model->center_y;
|
||||
x = model->x_width-RIGHT_OUTER_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
y = TOP_OUTER_ROW;
|
||||
x = model->center_x-1;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
y = model->y_height-BOT_OUTER_ROW;
|
||||
x = model->center_x-CENTER_CMTPLL_O;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
|
||||
for (x = 0; x < model->x_width; x++) {
|
||||
if (is_atx(X_LEFT_IO_DEVS_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (is_aty(Y_LEFT_WIRED, model, y)) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
}
|
||||
if (!is_aty(Y_LEFT_WIRED, model, y))
|
||||
continue;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
}
|
||||
}
|
||||
if (is_atx(X_RIGHT_IO_DEVS_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (is_aty(Y_RIGHT_WIRED, model, y)) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
}
|
||||
if (!is_aty(Y_RIGHT_WIRED, model, y))
|
||||
continue;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
}
|
||||
}
|
||||
if (is_atx(X_CENTER_CMTPLL_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
if (tile->flags & TF_PLL_DEV)
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
if (!(YX_TILE(model, y, x)->flags & TF_PLL_DEV))
|
||||
continue;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -251,35 +307,35 @@ int init_devices(struct fpga_model* model)
|
|||
if (is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS,
|
||||
model, y))
|
||||
continue;
|
||||
tile = YX_TILE(model, y, x);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
}
|
||||
}
|
||||
if (is_atx(X_LOGIC_COL, model, x)
|
||||
&& !is_atx(X_ROUTING_NO_IO, model, x-1)) {
|
||||
for (i = 0; i <= 1; i++) {
|
||||
tile = YX_TILE(model, TOP_IO_TILES+i, x);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
tile = YX_TILE(model, model->y_height-BOT_IO_TILES-i-1, x);
|
||||
tile->devices[tile->num_devices++].type = DEV_TIEOFF;
|
||||
y = TOP_IO_TILES+i;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
y = model->y_height-BOT_IO_TILES-i-1;
|
||||
if ((rc = add_dev(model, y, x, DEV_TIEOFF, 0))) goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
// LOGIC
|
||||
for (x = 0; x < model->x_width; x++) {
|
||||
if (is_atx(X_LOGIC_COL, model, x)) {
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
tile = YX_TILE(model, y, x);
|
||||
if (tile->flags & TF_LOGIC_XM_DEV) {
|
||||
tile->devices[tile->num_devices++].type = DEV_LOGIC_X;
|
||||
tile->devices[tile->num_devices++].type = DEV_LOGIC_M;
|
||||
}
|
||||
if (tile->flags & TF_LOGIC_XL_DEV) {
|
||||
tile->devices[tile->num_devices++].type = DEV_LOGIC_X;
|
||||
tile->devices[tile->num_devices++].type = DEV_LOGIC_L;
|
||||
}
|
||||
if (!is_atx(X_LOGIC_COL, model, x))
|
||||
continue;
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) {
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_M))) goto fail;
|
||||
}
|
||||
if (YX_TILE(model, y, x)->flags & TF_LOGIC_XL_DEV) {
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_L))) goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -137,13 +137,36 @@ int has_device(struct fpga_model* model, int y, int x, int dev)
|
|||
struct fpga_tile* tile = YX_TILE(model, y, x);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tile->num_devices; i++) {
|
||||
if (tile->devices[i].type == dev)
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
if (tile->devs[i].type == dev)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int has_device_type(struct fpga_model* model, int y, int x, int dev, int subtype)
|
||||
{
|
||||
struct fpga_tile* tile = YX_TILE(model, y, x);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tile->num_devs; i++) {
|
||||
if (tile->devs[i].type == dev) {
|
||||
switch (dev) {
|
||||
case DEV_LOGIC:
|
||||
if (tile->devs[i].logic.subtype == subtype)
|
||||
return 1;
|
||||
break;
|
||||
case DEV_IOB:
|
||||
if (tile->devs[i].iob.subtype == subtype)
|
||||
return 1;
|
||||
break;
|
||||
default: EXIT(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int add_connpt_2(struct fpga_model* model, int y, int x,
|
||||
const char* connpt_name, const char* suffix1, const char* suffix2)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@ int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* column
|
|||
void fpga_free_model(struct fpga_model* model)
|
||||
{
|
||||
if (!model) return;
|
||||
free_devices(model);
|
||||
free(model->tmp_str);
|
||||
strarray_free(&model->str);
|
||||
free(model->tiles);
|
||||
|
|
|
@ -46,14 +46,13 @@ static int init_logic_tile(struct fpga_model* model, int y, int x)
|
|||
int rc, i, j, ml;
|
||||
const char* xp;
|
||||
|
||||
if (has_device(model, y, x, DEV_LOGIC_M)) {
|
||||
if (has_device_type(model, y, x, DEV_LOGIC, LOGIC_M)) {
|
||||
ml = 'M';
|
||||
xp = "X";
|
||||
} else if (has_device(model, y, x, DEV_LOGIC_L)) {
|
||||
} else if (has_device_type(model, y, x, DEV_LOGIC, LOGIC_L)) {
|
||||
ml = 'L';
|
||||
xp = "XX";
|
||||
} else
|
||||
EXIT(1);
|
||||
} else EXIT(1);
|
||||
|
||||
if ((rc = add_switch(model, y, x,
|
||||
pf("CLEX%c_CLK0", ml), pf("%s_CLK", xp), 0 /* bidir */))) goto xout;
|
||||
|
@ -137,8 +136,7 @@ static int init_logic_switches(struct fpga_model* model)
|
|||
if (!is_atx(X_LOGIC_COL, model, x))
|
||||
continue;
|
||||
for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) {
|
||||
if (has_device(model, y, x, DEV_LOGIC_M)
|
||||
|| has_device(model, y, x, DEV_LOGIC_L)) {
|
||||
if (has_device(model, y, x, DEV_LOGIC)) {
|
||||
rc = init_logic_tile(model, y, x);
|
||||
if (rc) goto xout;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user