wrote pair2net utility to build nets out of connection pairs
This commit is contained in:
parent
f76a9a5d52
commit
eac8090301
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -12,3 +12,5 @@ sort_seq
|
|||
sort_seq.o
|
||||
merge_seq
|
||||
merge_seq.o
|
||||
pair2net
|
||||
pair2net.o
|
||||
|
|
25
Makefile
25
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 \
|
||||
|
|
1
README
1
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
|
||||
|
|
24
model.c
24
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
|
||||
|
|
36
model.h
36
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
|
||||
|
|
28
new_fp.c
28
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;
|
||||
}
|
||||
|
||||
|
|
203
pair2net.c
Normal file
203
pair2net.c
Normal file
|
@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#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 <data_file> | '-' 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user