From eac809030114522f42e0ebdfbeb0028830e43ff3 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Thu, 2 Aug 2012 03:45:59 +0200 Subject: [PATCH] wrote pair2net utility to build nets out of connection pairs --- .gitignore | 2 + Makefile | 25 +++++-- README | 1 + model.c | 24 ++++++- model.h | 36 +++++++++- new_fp.c | 28 +++++++- pair2net.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 310 insertions(+), 9 deletions(-) create mode 100644 pair2net.c diff --git a/.gitignore b/.gitignore index e674312..5af1966 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ sort_seq sort_seq.o merge_seq merge_seq.o +pair2net +pair2net.o diff --git a/Makefile b/Makefile index a151aab..76376b3 100644 --- a/Makefile +++ b/Makefile @@ -25,12 +25,16 @@ bit2txt: bit2txt.o helper.o bit2txt.o: bit2txt.c helper.h -hstrrep: hstrrep.o helper.o +pair2net: pair2net.o helper.o + +pair2net.o: pair2net.c helper.h sort_seq: sort_seq.o merge_seq: merge_seq.o +hstrrep: hstrrep.o helper.o + helper.o: helper.c helper.h model.o: model.c model.h @@ -54,19 +58,28 @@ compare.%: xc6slx9_empty.% @if test -s compare_$*_extra.txt; then echo Extra lines - compare_$*_extra.txt: ; cat compare_$*_extra.txt; fi; %.tiles: %.fp - cat $<|awk '{if ($$1=="tile" && $$4=="name") printf "%s %s %s\n",$$2,$$3,$$5}'|sort >$@ + @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 >$@ + @cat $<|awk '{if ($$1=="device") 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 >$@ + @echo Number of nets: + @cat $@|wc -l + @echo Number of connection points: + @cat $@|wc -w + @echo Largest net: + @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=="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 >$@ %.ports: %.fp - cat $<|awk '{if ($$1=="port") printf "%s %s %s\n",$$2,$$3,$$4}'|sort >$@ + @cat $<|awk '{if ($$1=="port") printf "%s %s %s\n",$$2,$$3,$$4}'|sort >$@ %.sw: %.fp sort_seq merge_seq - cat $<|awk '{if ($$1=="switch") printf "%s %s %s %s %s\n",$$2,$$3,$$4,$$5,$$6}'|sort|./sort_seq -|./merge_seq -|sort >$@ + @cat $<|awk '{if ($$1=="switch") printf "%s %s %s %s %s\n",$$2,$$3,$$4,$$5,$$6}'|sort|./sort_seq -|./merge_seq -|sort >$@ clean: rm -f bit2txt bit2txt.o \ diff --git a/README b/README index f360c9b..c87f9b8 100644 --- a/README +++ b/README @@ -16,3 +16,4 @@ Utilities - hstrrep high-speed hashed array based search and replace util - sort_seq sorts line-based text file by sequence numbers in strings - merge_seq merges a pre-sorted text file into wire sequences +- pair2net reads the first two words per line and builds nets diff --git a/model.c b/model.c index 332f4c2..2cd9175 100644 --- a/model.c +++ b/model.c @@ -113,6 +113,28 @@ static int init_switches(struct fpga_model* model) static int init_devices(struct fpga_model* model) { + int x, y; + struct fpga_tile* tile; + + for (x = 0; x < model->tile_x_range; x++) { + if (is_atx(X_LOGIC_COL, model, x)) { + for (y = TOP_IO_TILES; y < model->tile_y_range - BOTTOM_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->num_devices++; + tile->devices[tile->num_devices].type = DEV_LOGIC_M; + tile->num_devices++; + } + if (tile->flags & TF_LOGIC_XL_DEV) { + tile->devices[tile->num_devices].type = DEV_LOGIC_X; + tile->num_devices++; + tile->devices[tile->num_devices].type = DEV_LOGIC_L; + tile->num_devices++; + } + } + } + } return 0; } @@ -121,7 +143,7 @@ static int init_ports(struct fpga_model* model) int x, y, i, j, k, row_num, row_pos, rc; for (x = 0; x < model->tile_x_range; x++) { - if (is_atx(X_FABRIC_ROUTING_COL|X_CENTER_ROUTING_COL|X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x)) { + if (is_atx(X_ROUTING_COL, model, x)) { for (y = TOP_IO_TILES; y < model->tile_y_range - BOTTOM_IO_TILES; y++) { int keep_out = is_atx(X_ROUTING_NO_IO|X_LEFT_IO_ROUTING_COL|X_RIGHT_IO_ROUTING_COL, model, x) ? 0 : 2; if (y < TOP_IO_TILES+keep_out diff --git a/model.h b/model.h index 264731f..0657459 100644 --- a/model.h +++ b/model.h @@ -224,6 +224,40 @@ int is_atyx(int check, struct fpga_model* model, int y, int x); void is_in_row(const struct fpga_model* model, int y, int* row_num, int* row_pos); +enum fpgadev_type +{ + DEV_LOGIC_M, + DEV_LOGIC_L, + DEV_LOGIC_X, + DEV_MACC, + DEV_BRAM +}; + +struct fpgadev_logic_x +{ + int a; +}; + +struct fpgadev_logic_l +{ + int b; +}; + +struct fpgadev_logic_m +{ + int c; +}; + +struct fpga_device +{ + enum fpgadev_type type; + union { + struct fpgadev_logic_m log_m; + struct fpgadev_logic_l log_l; + struct fpgadev_logic_x log_x; + }; +}; + #define SWITCH_BIDIRECTIONAL 0x40000000 struct fpga_tile @@ -233,7 +267,7 @@ struct fpga_tile // expect up to 64 devices per tile int num_devices; - struct fpga_device* devices; + struct fpga_device devices[32]; // expect up to 5k connection point names per tile // 2*16 bit per entry diff --git a/new_fp.c b/new_fp.c index 007ba67..2e93665 100644 --- a/new_fp.c +++ b/new_fp.c @@ -114,7 +114,33 @@ int printf_tiles(struct fpga_model* model) int printf_devices(struct fpga_model* model) { - // device y01 x02 type + int x, y, i; + struct fpga_tile* tile; + + for (x = 0; x < model->tile_x_range; x++) { + for (y = 0; y < model->tile_y_range; y++) { + tile = YX_TILE(model, y, x); + for (i = 0; i < tile->num_devices; i++) { + switch (tile->devices[i].type) { + case DEV_LOGIC_M: + printf("device y%02i x%02i SLICEM\n", y, x); + break; + case DEV_LOGIC_L: + printf("device y%02i x%02i SLICEL\n", y, x); + break; + case DEV_LOGIC_X: + printf("device y%02i x%02i SLICEX\n", y, x); + break; + case DEV_MACC: + printf("device y%02i x%02i DSP48A1\n", y, x); + break; + case DEV_BRAM: + printf("device y%02i x%02i RAMB16BWER\n", y, x); + break; + } + } + } + } return 0; } diff --git a/pair2net.c b/pair2net.c new file mode 100644 index 0000000..890f9d5 --- /dev/null +++ b/pair2net.c @@ -0,0 +1,203 @@ +// +// Author: Wolfgang Spraul +// +// This is free and unencumbered software released into the public domain. +// For details see the UNLICENSE file at the root of the source tree. +// + +#include +#include +#include +#include +#include +#include + +#include "helper.h" + +#define ALLOC_INCREMENT 16 + +int add_entry(uint32_t** net, uint32_t new_idx) +{ + if (!*net) { + *net = malloc(ALLOC_INCREMENT*sizeof(**net)); + if (!(*net)) { + fprintf(stderr, "Out of memory in %s:%i\n", + __FILE__, __LINE__); + return -1; + } + **net = 1; + } else { + uint32_t num_entries = **net; + if (!(num_entries % ALLOC_INCREMENT)) { + void* new_ptr = realloc(*net, + (num_entries + ALLOC_INCREMENT)*sizeof(**net)); + if (!new_ptr) { + fprintf(stderr, "Out of memory in %s:%i\n", + __FILE__, __LINE__); + return -1; + } + *net = new_ptr; + } + } + (*net)[**net] = new_idx; + (**net)++; + return 0; +} + +int print_nets(uint32_t** nets, struct hashed_strarray* connpt_names) +{ + int i, j, num_connpoints, num_nets, largest_net, total_net_connpoints; + const char* str; + + num_connpoints = 0; + num_nets = 0; + largest_net = 0; + total_net_connpoints = 0; + + for (i = 0; i < STRIDX_1M; i++) { + if (nets[i]) { + num_connpoints++; + if (!((uint64_t)nets[i] & 1)) { + num_nets++; + if (!(*nets[i])) + fprintf(stderr, "Internal error - 0 entries in net %i\n", i); + total_net_connpoints += *nets[i] - 1; + if (*nets[i] - 1 > largest_net) + largest_net = *nets[i] - 1; + for (j = 1; j < *nets[i]; j++) { + str = strarray_lookup(connpt_names, nets[i][j]); + if (!str) { + fprintf(stderr, "Internal error - cannot find str %i\n", nets[i][j]); + continue; + } + if (j > 1) fputc(' ', stdout); + fputs(str, stdout); + } + fputc('\n', stdout); + } + } + } + return 0; +} + +struct hashed_strarray* g_sort_connpt_names; + +int sort_net(const void* a, const void* b) +{ + const uint32_t* _a, *_b; + const char* a_str, *b_str; + + _a = a; + _b = b; + a_str = strarray_lookup(g_sort_connpt_names, *_a); + b_str = strarray_lookup(g_sort_connpt_names, *_b); + if (!a_str || !b_str) { + fprintf(stderr, "Internal error in %s:%i - cannot find str %i or %i\n", + __FILE__, __LINE__, *_a, *_b); + return 0; + } + return strcmp(a_str, b_str); +} + +int sort_nets(uint32_t** nets, struct hashed_strarray* connpt_names) +{ + int i; + + g_sort_connpt_names = connpt_names; + for (i = 0; i < STRIDX_1M; i++) { + if (nets[i] && !((uint64_t)nets[i] & 1)) { + qsort(&nets[i][1], *nets[i]-1, sizeof(nets[i][1]), sort_net); + } + } + return 0; +} + +int main(int argc, char** argv) +{ + char line[1024], point_a[1024], point_b[1024]; + struct hashed_strarray connpt_names; + FILE* fp = 0; + int i, rc, point_a_idx, point_b_idx, existing_net_idx, new_net_idx; + int net_data_idx; + uint32_t** nets; + + if (argc < 2) { + fprintf(stderr, + "\n" + "pair2net - finds all pairs connected to the same net\n" + "Usage: %s | '-' for stdin\n", argv[0]); + goto xout; + } + if (strarray_init(&connpt_names, STRIDX_1M)) { + fprintf(stderr, "Out of memory in %s:%i\n", __FILE__, __LINE__); + goto xout; + } + + nets = calloc(STRIDX_1M, sizeof(*nets)); + if (!nets) { + fprintf(stderr, "Out of memory in %s:%i\n", __FILE__, __LINE__); + goto xout; + } + if (!strcmp(argv[1], "-")) + fp = stdin; + else { + fp = fopen(argv[1], "r"); + if (!fp) { + fprintf(stderr, "Error opening %s.\n", argv[1]); + goto xout; + } + } + while (fgets(line, sizeof(line), fp)) { + i = sscanf(line, "%s%s", point_a, point_b); + if (i != 2) continue; + + i = strlen(point_b); + if (i && point_b[i-1] == '\n') + point_b[i-1] = 0; + rc = strarray_add(&connpt_names, point_a, &point_a_idx); + if (rc) { + fprintf(stderr, "Out of memory in %s:%i\n", + __FILE__, __LINE__); + goto xout; + } + rc = strarray_add(&connpt_names, point_b, &point_b_idx); + if (rc) { + fprintf(stderr, "Out of memory in %s:%i\n", + __FILE__, __LINE__); + goto xout; + } + if (nets[point_a_idx] && nets[point_b_idx]) { + continue;} + if (nets[point_a_idx] || nets[point_b_idx]) { + if (nets[point_a_idx]) { + existing_net_idx = point_a_idx; + new_net_idx = point_b_idx; + } else { // point_b_idx exists + existing_net_idx = point_b_idx; + new_net_idx = point_a_idx; + } + if ((uint64_t) nets[existing_net_idx] & 1) + net_data_idx = (uint64_t) nets[existing_net_idx] >> 32; + else + net_data_idx = existing_net_idx; + // add new_net_idx to net data + rc = add_entry(&nets[net_data_idx], new_net_idx); + if (rc) goto xout; + // point to net data from new_net_idx + nets[new_net_idx] = (uint32_t*) (((uint64_t) net_data_idx << 32) | 1); + } else { + rc = add_entry(&nets[point_a_idx], point_a_idx); + if (rc) goto xout; + rc = add_entry(&nets[point_a_idx], point_b_idx); + if (rc) goto xout; + nets[point_b_idx] = (uint32_t*) (((uint64_t) point_a_idx << 32) | 1); + } + } + rc = sort_nets(nets, &connpt_names); + if (rc) goto xout; + rc = print_nets(nets, &connpt_names); + if (rc) goto xout; + return EXIT_SUCCESS; +xout: + return EXIT_FAILURE; +}