diff --git a/Makefile b/Makefile index 5867e4c..c02d045 100644 --- a/Makefile +++ b/Makefile @@ -7,41 +7,83 @@ # .PHONY: all clean +.SECONDARY: CFLAGS = -Wall -g LDLIBS = -lxml2 -all: bit2txt draw_svg_tiles new_fp hstrrep sort_seq merge_seq xc6slx9.svg xc6slx9.fp +all: bit2txt draw_svg_tiles new_fp hstrrep sort_seq merge_seq -xc6slx9.svg: draw_svg_tiles - ./draw_svg_tiles | xmllint --pretty 1 - > $@ +new_fp: new_fp.o model.o helper.o -xc6slx9.fp: new_fp - ./new_fp > $@ +new_fp.o: new_fp.c model.h helper.h + +draw_svg_tiles: draw_svg_tiles.o model.o helper.o + +draw_svg_tiles.o: draw_svg_tiles.c model.h helper.h bit2txt: bit2txt.o helper.o bit2txt.o: bit2txt.c helper.h -helper.o: helper.c helper.h - -model.o: model.c model.h - -new_fp.o: new_fp.c model.h helper.h - -draw_svg_tiles.o: draw_svg_tiles.c model.h helper.h - -draw_svg_tiles: draw_svg_tiles.o model.o helper.o - -new_fp: new_fp.o model.o helper.o - hstrrep: hstrrep.o helper.o sort_seq: sort_seq.o merge_seq: merge_seq.o +helper.o: helper.c helper.h + +model.o: model.c model.h + +xc6slx9_empty.fp: new_fp model.c model.h + ./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.%: xc6slx9_empty.% + @comm -1 -2 $< compare_other.$* > compare_$*_matching.txt + @echo Matching lines - compare_$*_matching.txt: + @cat compare_$*_matching.txt | wc -l + @diff -u compare_other.$* $< > compare_$*_diff.txt || true + @echo Missing lines - compare_$*_diff.txt + @cat compare_$*_diff.txt | grep ^-y | wc -l + @cat compare_$*_diff.txt | grep ^+y > compare_$*_extra.txt || true + @echo Extra lines - compare_$*_extra.txt: + @if test -s compare_$*_extra.txt; then cat compare_$*_extra.txt; else echo None; fi; + +%.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 >$@ + +%.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 >$@ + +%.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 >$@ + clean: - rm -f bit2txt bit2txt.o \ - draw_svg_tiles draw_svg_tiles.o \ - new_fp new_fp.o \ - helper.o model.o + rm -f bit2txt bit2txt.o \ + draw_svg_tiles draw_svg_tiles.o \ + new_fp new_fp.o \ + helper.o model.o hstrrep hstrrep.o \ + sort_seq sort_seq.o \ + merge_seq merge_seq.o \ + xc6slx9_empty.fp xc6slx9_empty.conns xc6slx9_empty.ports \ + xc6slx9.svg \ + compare_other.tiles compare_other.devices compare_other.conns compare_other.ports \ + compare_other.sw \ + xc6slx9_empty.tiles xc6slx9_empty.devices xc6slx9_empty.conns \ + xc6slx9_empty.ports xc6slx9_empty.sw \ + 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_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 diff --git a/hstrrep.c b/hstrrep.c index 94ad473..e834085 100644 --- a/hstrrep.c +++ b/hstrrep.c @@ -28,8 +28,8 @@ int main(int argc, char** argv) "\n" "hstrrep - hashed string replace\n" "Usage: %s \n" - " token_file has 2 words per line: First word is string\n" - " that is to be replaced, second word is the replacement.\n", argv[0]); + " token_file is parsed into two parts: first word is the string\n" + " that is to be replaced, rest of line the replacement.\n", argv[0]); goto xout; } diff --git a/merge_seq.c b/merge_seq.c index 6046b47..d67428d 100644 --- a/merge_seq.c +++ b/merge_seq.c @@ -279,13 +279,17 @@ int main(int argc, char** argv) if (argc < 2) { fprintf(stderr, "merge_seq - merge sequence (needs presorted file)\n" - "Usage: %s \n", argv[0]); + "Usage: %s | - for stdin\n", argv[0]); goto xout; } - fp = fopen(argv[1], "r"); - if (!fp) { - fprintf(stderr, "Error opening %s.\n", argv[1]); - 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; + } } // read first line @@ -317,7 +321,6 @@ int main(int argc, char** argv) rc = print_line(&first_line); if (rc) goto xout; out: - fclose(fp); return EXIT_SUCCESS; xout: return rc; diff --git a/model.c b/model.c index a7a4e86..53af43d 100644 --- a/model.c +++ b/model.c @@ -378,7 +378,7 @@ struct w_net // the %i in the name from 0:last_inc, for a total // of last_inc+1 wires. int last_inc; - struct w_point pts[22]; + struct w_point pts[40]; }; int add_conn_net(struct fpga_model* model, add_conn_f add_conn_func, struct w_net* net) @@ -423,6 +423,7 @@ void seed_strx(struct fpga_model* model, struct seed_data* data) int run_gclk(struct fpga_model* model); int run_gclk_horiz_regs(struct fpga_model* model); +int run_gclk_vert_regs(struct fpga_model* model); int run_wires(struct fpga_model* model) { @@ -432,6 +433,7 @@ int run_wires(struct fpga_model* model) rc = run_gclk(model); if (rc) goto xout; +return 0; for (y = 0; y < model->tile_y_range; y++) { for (x = 0; x < model->tile_x_range; x++) { @@ -848,6 +850,8 @@ if (x < model->center_x) { } rc = run_gclk_horiz_regs(model); if (rc) goto xout; + rc = run_gclk_vert_regs(model); + if (rc) goto xout; return 0; xout: return rc; @@ -1130,6 +1134,65 @@ xout: return rc; } +int run_gclk_vert_regs(struct fpga_model* model) +{ + struct w_net net; + int rc, i; + + // net tying together 15 gclk lines from row 10..27 + net.last_inc = 15; + for (i = 0; i <= 17; i++) { + if (is_aty(Y_ROW_HORIZ_AXSYMM, model, i+10)) + net.pts[i].name = "CLKV_GCLKH_MAIN%i_FOLD"; + else if (i == 9) // row 19 + net.pts[i].name = "CLKV_GCLK_MAIN%i_BUF"; + else + net.pts[i].name = "CLKV_GCLK_MAIN%i_FOLD"; + net.pts[i].start_count = 0; + net.pts[i].y = i+10; + net.pts[i].x = model->center_x; + } + net.pts[i].name = ""; + if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout; + + // net tying together 15 gclk lines from row 19..53 + net.last_inc = 15; + for (i = 0; i <= 34; i++) { // row 19..53 + if (is_aty(Y_ROW_HORIZ_AXSYMM, model, i+19)) + net.pts[i].name = "REGV_GCLKH_MAIN%i"; + else if (is_aty(Y_CHIP_HORIZ_REGS, model, i+19)) + net.pts[i].name = "CLKC_GCLK_MAIN%i"; + else if (i == 16) // row 35 + net.pts[i].name = "CLKV_GCLK_MAIN%i_BRK"; + else + net.pts[i].name = "CLKV_GCLK_MAIN%i"; + net.pts[i].start_count = 0; + net.pts[i].y = i+19; + net.pts[i].x = model->center_x; + } + net.pts[i].name = ""; + if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout; + + // net tying together 15 gclk lines from row 45..62 + net.last_inc = 15; + for (i = 0; i <= 17; i++) { + if (is_aty(Y_ROW_HORIZ_AXSYMM, model, i+45)) + net.pts[i].name = "CLKV_GCLKH_MAIN%i_FOLD"; + else if (i == 8) // row 53 + net.pts[i].name = "CLKV_GCLK_MAIN%i_BUF"; + else + net.pts[i].name = "CLKV_GCLK_MAIN%i_FOLD"; + net.pts[i].start_count = 0; + net.pts[i].y = i+45; + net.pts[i].x = model->center_x; + } + net.pts[i].name = ""; + if ((rc = add_conn_net(model, NOPREF_BI_F, &net))) goto xout; + return 0; +xout: + return rc; +} + static char next_non_whitespace(const char* s) { int i; @@ -1778,4 +1841,3 @@ const char* fpga_tiletype_str(enum fpga_tile_type type) || !fpga_ttstr[type]) return "UNK"; return fpga_ttstr[type]; } - diff --git a/new_fp.c b/new_fp.c index caac3a1..6b9d105 100644 --- a/new_fp.c +++ b/new_fp.c @@ -54,6 +54,9 @@ int main(int argc, char** argv) if (rc) goto fail; // todo: static_net + // port y01 x02 name + // device y01 x02 type + // switch y01 x02 from direction(->|<->) to return EXIT_SUCCESS; fail: @@ -70,224 +73,51 @@ int printf_tiles(struct fpga_model* model) for (y = 0; y < model->tile_y_range; y++) { tile = &model->tiles[y*model->tile_x_range + x]; - printf("tile y%02i x%02i", y, x); - - if (tile->type == NA && !(tile->flags)) { - printf(" -\n"); - continue; - } if (tile->type != NA) - printf(" name %s", fpga_tiletype_str(tile->type)); + printf("tile y%02i x%02i name %s\n", y, x, + fpga_tiletype_str(tile->type)); if (tile->flags) { int tf = tile->flags; - printf(" flags"); + printf("tile y%02i x%02i flags", y, x); PRINT_FLAG(TF_LOGIC_XL_DEV); PRINT_FLAG(TF_LOGIC_XM_DEV); PRINT_FLAG(TF_IOLOGIC_DELAY_DEV); + PRINT_FLAG(TF_FABRIC_ROUTING_COL); + PRINT_FLAG(TF_FABRIC_LOGIC_COL); + PRINT_FLAG(TF_FABRIC_BRAM_MACC_ROUTING_COL); + PRINT_FLAG(TF_FABRIC_BRAM_COL); + PRINT_FLAG(TF_FABRIC_MACC_COL); + PRINT_FLAG(TF_BRAM_DEV); + PRINT_FLAG(TF_MACC_DEV); + PRINT_FLAG(TF_LOGIC_XL_DEV); + PRINT_FLAG(TF_LOGIC_XM_DEV); + PRINT_FLAG(TF_IOLOGIC_DELAY_DEV); + PRINT_FLAG(TF_DCM_DEV); + PRINT_FLAG(TF_PLL_DEV); - if (tf) - printf(" 0x%x", tf); + if (tf) printf(" 0x%x", tf); + printf("\n"); } - printf("\n"); } } return 0; } -struct conn_printf_data -{ - int src_x, src_y; // src_x is -1 for empty entry - char src_conn_point[41]; - int num_combined_wires; // 0 for no suffix, otherwise 4 for 0:3 etc. - int dest_x, dest_y; - char dest_conn_point[41]; -}; - -#define MAX_CONN_PRINTF_ENTRIES 40000 -static struct conn_printf_data s_conn_printf_buf[MAX_CONN_PRINTF_ENTRIES]; -static int s_conn_printf_entries; - -int sort_by_tile(const void* a, const void* b) -{ - int i, rc; - - struct conn_printf_data* _a = (struct conn_printf_data*) a; - struct conn_printf_data* _b = (struct conn_printf_data*) b; - - if (_a->src_x < 0 && _b->src_x < 0) return 0; - if (_a->src_x < 0) return -1; - if (_b->src_x < 0) return 1; - - if (_a->src_x != _b->src_x) - return _a->src_x - _b->src_x; - if (_a->src_y != _b->src_y) - return _a->src_y - _b->src_y; - if (_a->dest_x != _b->dest_x) - return _a->dest_x - _b->dest_x; - if (_a->dest_y != _b->dest_y) - return _a->dest_y - _b->dest_y; - if (_a->num_combined_wires != _b->num_combined_wires) - return _b->num_combined_wires - _a->num_combined_wires; - - rc = compare_with_number(_a->src_conn_point, _b->src_conn_point); - if (rc) return rc; - - // following is a special version of strcmp(_a->dest_conn_point, _b->dest_conn_point) - // to push '_' before digits. - for (i = 0; _a->dest_conn_point[i]; i++) { - if (_a->dest_conn_point[i] != _b->dest_conn_point[i]) { - // The point here is to get a NN2B0 -> NN2E_S0 before - // a NN2B0 -> NN2E0 so that later wire combinations - // are easier. - if (_a->dest_conn_point[i] >= '0' && _a->dest_conn_point[i] <= '9' - && _b->dest_conn_point[i] == '_') - return 1; - if (_b->dest_conn_point[i] >= '0' && _b->dest_conn_point[i] <= '9' - && _a->dest_conn_point[i] == '_') - return -1; - return _a->dest_conn_point[i] - _b->dest_conn_point[i]; - } - } - return _a->dest_conn_point[i] - _b->dest_conn_point[i]; -} - -int find_last_wire_digit(const char* wire_str, int* start_o, int* end_o, int* num) -{ - // There are some known suffixes that may confuse our - // 'last digit' logic so we skip those. - static const char suffix[8][16] = - { "_S0", "_N3", "_INT0", "_INT1", "_INT2", "_INT3", "" }; - int i, suffix_len, right_bound, _end_o, base; - - right_bound = strlen(wire_str); - for (i = 0; suffix[i][0]; i++) { - suffix_len = strlen(suffix[i]); - if (right_bound > suffix_len - && !strcmp(&wire_str[right_bound - suffix_len], - suffix[i])) { - right_bound -= suffix_len; - break; - } - } - _end_o = -1; - for (i = right_bound; i; i--) { - if (wire_str[i-1] >= '0' && wire_str[i-1] <= '9' && _end_o == -1) { - _end_o = i; - continue; - } - if ((wire_str[i-1] < '0' || wire_str[i-1] > '9') && _end_o != -1) { - *start_o = i; - *end_o = _end_o; - *num = 0; - base = 1; - for (i = *end_o - 1; i >= *start_o; i--) { - *num += (wire_str[i] - '0')*base; - base *= 10; - } - return 1; - } - } - return 0; -} - -void sort_and_reduce_printf_buf() -{ - int src_digit_start_o, src_digit_end_o, src_digit; - int dest_digit_start_o, dest_digit_end_o, dest_digit; - int second_src_digit_start_o, second_src_digit_end_o, second_src_digit; - int second_dest_digit_start_o, second_dest_digit_end_o, second_dest_digit; - int i, j, sequence_size; - int sequence[100]; // support up to 100 elements in sequence - char old_suffix[41]; - - if (s_conn_printf_entries < 2) - return; - - // First sort by y/x src, then y/x dest, then src conn point, then - // dest conn points - all in preparation of the numbered wires reduction. - qsort(s_conn_printf_buf, s_conn_printf_entries, - sizeof(s_conn_printf_buf[0]), sort_by_tile); - - // Reduce numbered wire sets. - for (i = 0; i < s_conn_printf_entries-1; i++) { - if (s_conn_printf_buf[i].src_x < 0) - continue; - if (!find_last_wire_digit(s_conn_printf_buf[i].src_conn_point, &src_digit_start_o, &src_digit_end_o, &src_digit) - || !find_last_wire_digit(s_conn_printf_buf[i].dest_conn_point, &dest_digit_start_o, &dest_digit_end_o, &dest_digit)) - continue; - - // Search for a contiguous sequence of increasing numbers, but support - // skipping over unrelated pairs that may be inside our sequence due - // to sorting. - sequence[0] = i; - sequence_size = 1; - for (j = i+1; j < s_conn_printf_entries; j++) { - if (j > sequence[sequence_size-1]+4) // search over at most 4 non-matches - break; - if (s_conn_printf_buf[j].src_x < 0) - continue; - // is the j connection from and to the same tiles as the i connection? - if (s_conn_printf_buf[i].src_x != s_conn_printf_buf[j].src_x - || s_conn_printf_buf[i].src_y != s_conn_printf_buf[j].src_y - || s_conn_printf_buf[i].dest_x != s_conn_printf_buf[j].dest_x - || s_conn_printf_buf[i].dest_y != s_conn_printf_buf[j].dest_y) - continue; - if (!find_last_wire_digit(s_conn_printf_buf[j].src_conn_point, &second_src_digit_start_o, &second_src_digit_end_o, &second_src_digit)) - continue; - if (!find_last_wire_digit(s_conn_printf_buf[j].dest_conn_point, &second_dest_digit_start_o, &second_dest_digit_end_o, &second_dest_digit)) - continue; - if (second_src_digit != src_digit+sequence_size - || second_dest_digit != dest_digit+sequence_size) - continue; - if (src_digit_start_o != second_src_digit_start_o - || strncmp(s_conn_printf_buf[i].src_conn_point, s_conn_printf_buf[j].src_conn_point, src_digit_start_o)) - continue; - if (strcmp(&s_conn_printf_buf[i].src_conn_point[src_digit_end_o], &s_conn_printf_buf[j].src_conn_point[second_src_digit_end_o])) - continue; - if (dest_digit_start_o != second_dest_digit_start_o - || strncmp(s_conn_printf_buf[i].dest_conn_point, s_conn_printf_buf[j].dest_conn_point, dest_digit_start_o)) - continue; - if (strcmp(&s_conn_printf_buf[i].dest_conn_point[dest_digit_end_o], &s_conn_printf_buf[j].dest_conn_point[second_dest_digit_end_o])) - continue; - if (sequence_size >= sizeof(sequence)/sizeof(sequence[0])) { - fprintf(stderr, "Internal error - too long sequence in line %i\n", __LINE__); - break; - } - sequence[sequence_size++] = j; - } - if (sequence_size < 2) - continue; - strcpy(old_suffix, &s_conn_printf_buf[sequence[0]].src_conn_point[src_digit_end_o]); - sprintf(&s_conn_printf_buf[sequence[0]].src_conn_point[src_digit_start_o], "%i:%i%s", src_digit, src_digit+sequence_size-1, old_suffix); - strcpy(old_suffix, &s_conn_printf_buf[sequence[0]].dest_conn_point[dest_digit_end_o]); - sprintf(&s_conn_printf_buf[sequence[0]].dest_conn_point[dest_digit_start_o], "%i:%i%s", dest_digit, dest_digit+sequence_size-1, old_suffix); - s_conn_printf_buf[sequence[0]].num_combined_wires = sequence_size; - for (i = 1; i < sequence_size; i++) - s_conn_printf_buf[sequence[i]].src_x = -1; - i = sequence[0]; - } - - // Second round of sorting, this time the largest numbered wire - // sets are defined and will move up. - qsort(s_conn_printf_buf, s_conn_printf_entries, sizeof(s_conn_printf_buf[0]), - sort_by_tile); -} - int printf_static_conns(struct fpga_model* model) { struct fpga_tile* tile; char tmp_line[512]; const char* conn_point_name_src, *other_tile_connpt_str; uint16_t other_tile_connpt_str_i; - int x, y, i, j, conn_point_dests_o, num_dests_for_this_conn_point; + int x, y, i, j, k, conn_point_dests_o, num_dests_for_this_conn_point; int other_tile_x, other_tile_y, first_conn_printed; for (x = 0; x < model->tile_x_range; x++) { for (y = 0; y < model->tile_y_range; y++) { tile = &model->tiles[y*model->tile_x_range + x]; - s_conn_printf_entries = 0; + first_conn_printed = 0; for (i = 0; i < tile->num_conn_point_names; i++) { conn_point_dests_o = tile->conn_point_names[i*2]; if (i < tile->num_conn_point_names-1) @@ -313,38 +143,21 @@ int printf_static_conns(struct fpga_model* model) __LINE__, other_tile_connpt_str_i, other_tile_x, other_tile_y, x, y, j, num_dests_for_this_conn_point, conn_point_name_src); continue; } - s_conn_printf_buf[s_conn_printf_entries].src_y = y; - s_conn_printf_buf[s_conn_printf_entries].src_x = x; - strcpy(s_conn_printf_buf[s_conn_printf_entries].src_conn_point, conn_point_name_src); - s_conn_printf_buf[s_conn_printf_entries].num_combined_wires = 0; - s_conn_printf_buf[s_conn_printf_entries].dest_y = other_tile_y; - s_conn_printf_buf[s_conn_printf_entries].dest_x = other_tile_x; - strcpy(s_conn_printf_buf[s_conn_printf_entries].dest_conn_point, other_tile_connpt_str); - s_conn_printf_entries++; + + if (!first_conn_printed) { + first_conn_printed = 1; + printf("\n"); + } + sprintf(tmp_line, "static_conn y%02i x%02i %s ", + y, x, conn_point_name_src); + k = strlen(tmp_line); + while (k < 45) + tmp_line[k++] = ' '; + sprintf(&tmp_line[k], "y%02i x%02i %s\n", + other_tile_y, other_tile_x, other_tile_connpt_str); + printf(tmp_line); } } - sort_and_reduce_printf_buf(); - first_conn_printed = 0; - for (i = 0; i < s_conn_printf_entries; i++) { - if (s_conn_printf_buf[i].src_x < 0) - continue; - if (!first_conn_printed) { - printf("\n"); - first_conn_printed = 1; - } - sprintf(tmp_line, "static_conn y%02i-x%02i-%s ", - s_conn_printf_buf[i].src_y, - s_conn_printf_buf[i].src_x, - s_conn_printf_buf[i].src_conn_point); - j = strlen(tmp_line); - while (j < 45) - tmp_line[j++] = ' '; - sprintf(&tmp_line[j], "y%02i-x%02i-%s\n", - s_conn_printf_buf[i].dest_y, - s_conn_printf_buf[i].dest_x, - s_conn_printf_buf[i].dest_conn_point); - printf(tmp_line); - } } } return 0; diff --git a/sort_seq.c b/sort_seq.c index d0c24cd..836377b 100644 --- a/sort_seq.c +++ b/sort_seq.c @@ -106,13 +106,17 @@ int main(int argc, char** argv) if (argc < 2) { fprintf(stderr, "sort_seq - sort by sequence\n" - "Usage: %s \n", argv[0]); + "Usage: %s | - for stdin\n", argv[0]); goto xout; } - fp = fopen(argv[1], "r"); - if (!fp) { - fprintf(stderr, "Error opening %s.\n", argv[1]); - 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; + } } s_numlines = 0; // read 200 lines to beginning of buffer @@ -140,7 +144,6 @@ int main(int argc, char** argv) } else s_numlines = 0; } - fclose(fp); return EXIT_SUCCESS; xout: return EXIT_FAILURE;