diff --git a/.gitignore b/.gitignore index 257b03f..04f1ca4 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,7 @@ # binaries # draw_svg_tiles -new_fp +fpinfo hstrrep sort_seq merge_seq diff --git a/Makefile b/Makefile index a9eb26e..ccd3061 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ CFLAGS += -I$(CURDIR)/libs LDFLAGS += -Wl,-rpath,$(CURDIR)/libs OBJS = autotest.o bit2fp.o printf_swbits.o draw_svg_tiles.o fp2bit.o \ - hstrrep.o merge_seq.o new_fp.o pair2net.o sort_seq.o hello_world.o \ + hstrrep.o merge_seq.o fpinfo.o pair2net.o sort_seq.o hello_world.o \ blinking_led.o jtag_counter.o j1_blinking.o DYNAMIC_LIBS = libs/libfpga-model.so libs/libfpga-bit.so \ @@ -24,7 +24,7 @@ DYNAMIC_LIBS = libs/libfpga-model.so libs/libfpga-bit.so \ .SECONDARY: .SECONDEXPANSION: -all: new_fp fp2bit bit2fp printf_swbits draw_svg_tiles autotest hstrrep \ +all: fpinfo fp2bit bit2fp printf_swbits draw_svg_tiles autotest hstrrep \ sort_seq merge_seq pair2net hello_world blinking_led jtag_counter \ j1_blinking.o @@ -173,8 +173,8 @@ compare_%_sw.fco: compare_%.fp compare_%_swbits.fco: printf_swbits @./printf_swbits | sort > $@ -compare_%.fp: new_fp - @./new_fp >$@ +compare_%.fp: fpinfo + @./fpinfo >$@ # todo: .cnets not integrated yet %.cnets: %.fp pair2net @@ -206,7 +206,7 @@ bit2fp: bit2fp.o $(DYNAMIC_LIBS) printf_swbits: printf_swbits.o $(DYNAMIC_LIBS) -new_fp: new_fp.o $(DYNAMIC_LIBS) +fpinfo: fpinfo.o $(DYNAMIC_LIBS) draw_svg_tiles: CFLAGS += `pkg-config libxml-2.0 --cflags` draw_svg_tiles: LDLIBS += `pkg-config libxml-2.0 --libs` @@ -220,8 +220,8 @@ merge_seq: merge_seq.o $(DYNAMIC_LIBS) hstrrep: hstrrep.o $(DYNAMIC_LIBS) -xc6slx9.fp: new_fp - ./new_fp > $@ +xc6slx9.fp: fpinfo + ./fpinfo > $@ xc6slx9.svg: draw_svg_tiles ./draw_svg_tiles | xmllint --pretty 1 - > $@ @@ -229,7 +229,7 @@ xc6slx9.svg: draw_svg_tiles clean: @make -C libs clean rm -f $(OBJS) *.d - rm -f draw_svg_tiles new_fp hstrrep sort_seq merge_seq autotest + rm -f draw_svg_tiles fpinfo hstrrep sort_seq merge_seq autotest rm -f fp2bit bit2fp printf_swbits pair2net hello_world blinking_led rm -f jtag_counter j1_blinking rm -f xc6slx9.fp xc6slx9.svg diff --git a/README b/README index 8c12274..57e335c 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Introduction fpgatools converts the configuration of an FPGA between JSON and bitstream representation. - The only supported chips at this time is the xc6slx9, a 45nm-generation + The only supported chip at this time is the xc6slx9, a 45nm-generation FPGA with 5720 6-input LUTs, block ram and multiply-accumulate resources. @@ -33,7 +33,8 @@ Design Utilities - hello_world outputs an AND gate floorplan to stdout - blinking_led outputs blinking led design to stdout -- new_fp creates empty .fp floorplan file +- fpinfo outputs information about tiles, devices, ports, + connections and switches in a floorplan - fp2bit converts .fp floorplan into .bit bitstream - bit2fp converts .bit bitstream into .fp floorplan - draw_svg_tiles draws a simple .svg showing tile types @@ -53,12 +54,6 @@ Profiling ~# perf annotate ~# perf report -How to Help - - use fpgatools, email author for free support - - fund electron microscope photos - - want bigger or newer chips? email the author - - timing analysis, temperature analysis, visualizations - TODO (as of 2015-03) short-term (3 months): diff --git a/autotest.c b/autotest.c index 27a70d1..4e64503 100644 --- a/autotest.c +++ b/autotest.c @@ -103,9 +103,9 @@ static int diff_printf(struct test_state* tstate) dest_f = fopen(path, "w"); if (!dest_f) FAIL(errno); - rc = printf_devices(dest_f, tstate->model, /*config_only*/ 1); + rc = printf_devices(dest_f, tstate->model, /*config_only*/ 1, /*no_json*/ 1); if (rc) FAIL(rc); - rc = printf_nets(dest_f, tstate->model); + rc = printf_nets(dest_f, tstate->model, /*no_json*/ 1); if (rc) FAIL(rc); fclose(dest_f); @@ -382,7 +382,7 @@ static int test_switches(struct test_state* tstate, int y, int x, if (switch_str[2] == '4') { // base for len-4 wire if (tstate->dry_run) - fnet_printf(stdout, tstate->model, net); + fnet_printf(stdout, tstate->model, net, /*no_json*/ 1); rc = diff_printf(tstate); if (rc) FAIL(rc); @@ -420,7 +420,7 @@ static int test_switches(struct test_state* tstate, int y, int x, // base for len-4 target if (tstate->dry_run) - fnet_printf(stdout, tstate->model, net); + fnet_printf(stdout, tstate->model, net, /*no_json*/ 1); rc = diff_printf(tstate); if (rc) FAIL(rc); @@ -430,7 +430,7 @@ static int test_switches(struct test_state* tstate, int y, int x, if (rc) FAIL(rc); if (tstate->dry_run) - fnet_printf(stdout, tstate->model, net); + fnet_printf(stdout, tstate->model, net, /*no_json*/ 1); rc = diff_printf(tstate); if (rc) FAIL(rc); @@ -605,7 +605,7 @@ static int test_routing_sw_from_logic(struct test_state *tstate, swto.dest_x, conns.chain.set.sw, conns.chain.set.len); if (rc) FAIL(rc); if (tstate->dry_run) - fnet_printf(stdout, tstate->model, net); + fnet_printf(stdout, tstate->model, net, /*no_json*/ 1); rc = test_switches(tstate, conns.dest_y, conns.dest_x, conns.dest_str_i, net, done_list, done_list_len); diff --git a/bit2fp.c b/bit2fp.c index ba28064..fbfc65c 100644 --- a/bit2fp.c +++ b/bit2fp.c @@ -15,7 +15,7 @@ static void help_exit(int argc, char **argv) "\n" "%s - bitstream to floorplan\n" "Usage: %s [--help] [--verbose] [--bit-header] [--bit-regs] [--bit-crc]\n" - " %*s [--no-model] [--no-fp-header] \n" + " %*s [--no-model] [--no-json] \n" "\n", argv[0], argv[0], (int) strlen(argv[0]), ""); exit(EXIT_SUCCESS); } @@ -23,7 +23,7 @@ static void help_exit(int argc, char **argv) int main(int argc, char** argv) { struct fpga_model model; - int bit_header, bit_regs, bit_crc, fp_header, pull_model, file_arg; + int bit_header, bit_regs, bit_crc, json, pull_model, file_arg; int verbose, flags, rc = -1; struct fpga_config config; @@ -34,7 +34,7 @@ int main(int argc, char** argv) bit_regs = 0; bit_crc = 0; pull_model = 1; - fp_header = 1; + json = 1; file_arg = 1; while (file_arg < argc && !strncmp(argv[file_arg], "--", 2)) { if (!strcmp(argv[file_arg], "--help")) @@ -50,8 +50,8 @@ int main(int argc, char** argv) bit_crc = 1; else if (!strcmp(argv[file_arg], "--no-model")) pull_model = 0; - else if (!strcmp(argv[file_arg], "--no-fp-header")) - fp_header = 0; + else if (!strcmp(argv[file_arg], "--no-json")) + json = 0; else break; file_arg++; } @@ -83,7 +83,7 @@ int main(int argc, char** argv) // dump model flags = FP_DEFAULT; - if (!fp_header) flags |= FP_NO_HEADER; + if (!json) flags |= FP_NO_JSON; if ((rc = write_floorplan(stdout, &model, flags))) FAIL(rc); // dump what doesn't fit into the model diff --git a/new_fp.c b/fpinfo.c similarity index 81% rename from new_fp.c rename to fpinfo.c index b4077f3..454dc9d 100644 --- a/new_fp.c +++ b/fpinfo.c @@ -20,25 +20,32 @@ int main(int argc, char** argv) if (argc > 1 && !strcmp(argv[1], "--no-conns")) no_conns = 1; + printf("{\n"); printf_version(stdout); + printf(",\n"); rc = printf_tiles(stdout, &model); if (rc) goto fail; - rc = printf_devices(stdout, &model, /*config_only*/ 0); + printf(",\n"); + rc = printf_devices(stdout, &model, /*config_only*/ 0, /*no_json*/ 0); if (rc) goto fail; + printf(",\n"); rc = printf_ports(stdout, &model); if (rc) goto fail; if (!no_conns) { + printf(",\n"); rc = printf_conns(stdout, &model); if (rc) goto fail; } + printf(",\n"); rc = printf_switches(stdout, &model); if (rc) goto fail; + printf("\n}\n"); return EXIT_SUCCESS; fail: return rc; diff --git a/libs/bit_frames.c b/libs/bit_frames.c index 475460b..8df0715 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -2315,6 +2315,10 @@ static void destruct_extract_state(struct extract_state *es) es->yx_pos = 0; } +// +// bscan +// + static int extract_bscan(struct extract_state *es) { int enum_i, bscan_y, bscan_x, bscan_type_idx; @@ -2389,6 +2393,245 @@ static int write_bscan(struct fpga_bits *bits, struct fpga_model *model) RC_RETURN(model); } +// +// bram +// + +// Each RAMB16 stores configuration in 3 minors (22-24) and 16 vertical +// 16-bit words, for a total of 3*16*16 = 768 configuration bits per RAMB16. +// This does not include parity and initial data values which are stored +// in the data section. +// Minor 22 is for INIT and SRVAL A+B bits only (36*4=144 bits). + +enum bram_cfg_names { BRAM_ENABLED_TOP, BRAM_ENABLED_BOTTOM, + BRAM_ENA_HIGH, BRAM_ENB_HIGH, + BRAM_REGCEA_HIGH, BRAM_REGCEB_HIGH, + BRAM_RSTA_LOW, BRAM_RSTB_HIGH, + BRAM_WEA0_HIGH, BRAM_WEA1_HIGH, BRAM_WEA2_HIGH, + BRAM_WEA3_HIGH, + BRAM_WEB0_HIGH, BRAM_WEB1_HIGH, BRAM_WEB2_HIGH, + BRAM_WEB3_HIGH, + BRAM_RSTTYPE_ASYNC, + BRAM_DOA_REG, BRAM_DOB_REG, + BRAM_READ_FIRST_A, BRAM_NO_CHANGE_A, + BRAM_READ_FIRST_B, BRAM_NO_CHANGE_B, + BRAM_EN_RSTRAM_A, BRAM_EN_RSTRAM_B, + BRAM_RST_PRIORITY_A_CE, BRAM_RST_PRIORITY_B_CE, + BRAM_DATA_WIDTH_A_0, BRAM_DATA_WIDTH_A_2, BRAM_DATA_WIDTH_A_4, + BRAM_DATA_WIDTH_A_9, BRAM_DATA_WIDTH_A_18, + BRAM_DATA_WIDTH_A_36, + BRAM_DATA_WIDTH_B_0, BRAM_DATA_WIDTH_B_2, BRAM_DATA_WIDTH_B_4, + BRAM_DATA_WIDTH_B_9, BRAM_DATA_WIDTH_B_18, + BRAM_DATA_WIDTH_B_36, + BRAM_RAM_MODE_TDP, BRAM_RAM_MODE_SDP }; + +static const cfg_bits_t bram_bits[] = +{ + // minor v16 bits name + { 23, 0, 0x0040, BRAM_ENABLED_TOP }, + { 24, 0, 0x0600, BRAM_ENABLED_TOP }, + { 24, 1, 0xC000, BRAM_ENABLED_TOP }, + { 24, 5, 0x000C, BRAM_ENABLED_TOP }, + + { 24, 10, 0x3000, BRAM_ENABLED_BOTTOM }, + { 24, 14, 0x0003, BRAM_ENABLED_BOTTOM }, + { 23, 15, 0x0200, BRAM_ENABLED_BOTTOM }, + { 24, 15, 0x0060, BRAM_ENABLED_BOTTOM }, + + { 24, 5, 0x0080, BRAM_ENA_HIGH }, + { 24, 6, 0x0200, BRAM_ENA_HIGH }, + { 24, 6, 0x0500, BRAM_ENB_HIGH }, + { 23, 0, 0x0400, BRAM_REGCEA_HIGH }, + { 23, 15, 0x0020, BRAM_REGCEA_HIGH }, + { 23, 0, 0x0010, BRAM_REGCEB_HIGH }, + { 23, 15, 0x0800, BRAM_REGCEB_HIGH }, + { 23, 0, 0x1000, BRAM_RSTA_LOW }, + { 23, 15, 0x0008, BRAM_RSTA_LOW }, + { 23, 0, 0x0004, BRAM_RSTB_HIGH }, + { 23, 15, 0x2000, BRAM_RSTB_HIGH }, + + { 23, 15, 0x0040, BRAM_WEA0_HIGH }, + { 23, 15, 0x0010, BRAM_WEA1_HIGH }, + { 23, 0, 0x0200, BRAM_WEA2_HIGH }, + { 23, 0, 0x0800, BRAM_WEA3_HIGH }, + + { 23, 15, 0x1000, BRAM_WEB0_HIGH }, + { 23, 15, 0x4000, BRAM_WEB1_HIGH }, + { 23, 0, 0x0008, BRAM_WEB2_HIGH }, + { 23, 0, 0x0002, BRAM_WEB3_HIGH }, + + { 24, 0, 0x0080, BRAM_RSTTYPE_ASYNC }, + { 24, 1, 0x0100, BRAM_RSTTYPE_ASYNC }, + { 24, 14, 0x0080, BRAM_RSTTYPE_ASYNC }, + { 24, 15, 0x0100, BRAM_RSTTYPE_ASYNC }, + + { 24, 1, 0x0400, BRAM_DOA_REG }, + { 24, 14, 0x0020, BRAM_DOA_REG }, + { 24, 1, 0x0200, BRAM_DOB_REG }, + { 24, 14, 0x0040, BRAM_DOB_REG }, + + { 24, 0, 0x1000, BRAM_READ_FIRST_A }, + { 24, 15, 0x0008, BRAM_READ_FIRST_A }, + { 24, 0, 0x4000, BRAM_NO_CHANGE_A }, + { 24, 15, 0x0002, BRAM_NO_CHANGE_A }, + { 24, 0, 0x0800, BRAM_READ_FIRST_B }, + { 24, 15, 0x0010, BRAM_READ_FIRST_B }, + { 24, 0, 0x2000, BRAM_NO_CHANGE_B }, + { 24, 15, 0x0004, BRAM_NO_CHANGE_B }, + { 24, 1, 0x0002, BRAM_EN_RSTRAM_A }, + { 24, 14, 0x4000, BRAM_EN_RSTRAM_A }, + { 24, 5, 0x4000, BRAM_EN_RSTRAM_B }, + { 24, 10, 0x0002, BRAM_EN_RSTRAM_B }, + { 24, 0, 0x0040, BRAM_RST_PRIORITY_A_CE }, + { 24, 15, 0x0200, BRAM_RST_PRIORITY_A_CE }, + { 24, 0, 0x0020, BRAM_RST_PRIORITY_B_CE }, + { 24, 15, 0x0400, BRAM_RST_PRIORITY_B_CE }, + { 24, 0, 0x0015, BRAM_DATA_WIDTH_A_0 }, + { 24, 15, 0xA800, BRAM_DATA_WIDTH_A_0 }, + { 24, 0, 0x0001, BRAM_DATA_WIDTH_A_2 }, + { 24, 15, 0x8000, BRAM_DATA_WIDTH_A_2 }, + { 24, 0, 0x0004, BRAM_DATA_WIDTH_A_4 }, + { 24, 15, 0x2000, BRAM_DATA_WIDTH_A_4 }, + { 24, 0, 0x0005, BRAM_DATA_WIDTH_A_9 }, + { 24, 15, 0xA000, BRAM_DATA_WIDTH_A_9 }, + { 24, 0, 0x0010, BRAM_DATA_WIDTH_A_18 }, + { 24, 15, 0x0800, BRAM_DATA_WIDTH_A_18 }, + { 24, 0, 0x0011, BRAM_DATA_WIDTH_A_36 }, + { 24, 15, 0x8800, BRAM_DATA_WIDTH_A_36 }, + { 24, 0, 0x800A, BRAM_DATA_WIDTH_B_0 }, + { 24, 15, 0x5001, BRAM_DATA_WIDTH_B_0 }, + { 24, 0, 0x0002, BRAM_DATA_WIDTH_B_2 }, + { 24, 15, 0x4000, BRAM_DATA_WIDTH_B_2 }, + { 24, 0, 0x8000, BRAM_DATA_WIDTH_B_4 }, + { 24, 15, 0x0001, BRAM_DATA_WIDTH_B_4 }, + { 24, 0, 0x8002, BRAM_DATA_WIDTH_B_9 }, + { 24, 15, 0x4001, BRAM_DATA_WIDTH_B_9 }, + { 24, 0, 0x0008, BRAM_DATA_WIDTH_B_18 }, + { 24, 15, 0x1000, BRAM_DATA_WIDTH_B_18 }, + { 24, 0, 0x000A, BRAM_DATA_WIDTH_B_36 }, + { 24, 15, 0x5000, BRAM_DATA_WIDTH_B_36 }, + { 23, 0, 0x0080, BRAM_RAM_MODE_TDP }, + { 23, 15, 0x0200, BRAM_RAM_MODE_TDP }, + { 23, 1, 0x0100, BRAM_RAM_MODE_SDP }, + { 23, 15, 0x0080, BRAM_RAM_MODE_SDP }, + + { -1 } +}; + +// Use struct to avoid warnings/casts compared to pointer to array of int. +struct eight_words +{ + int w[8]; +}; + +static void extract_init_srval_18(struct eight_words* eight_words, int *init_a, + int *init_b, int *srval_a, int *srval_b); +static void extract_init_srval_36(struct eight_words* eight_top_words, + struct eight_words* eight_bot_words, int64_t *init_a, + int64_t *init_b, int64_t *srval_a, int64_t *srval_b); + +#define INIT_A 0x40000000 +#define SRVAL_A 0x20000000 +#define INIT_B 0x10000000 +#define SRVAL_B 0x08000000 +#define INIT_SRVAL_BITMASK 0x0000001F // max 17 (16-bit word plus 2 parity bits) + +static void extract_init_srval_18(struct eight_words* eight_words, int *init_a, + int *init_b, int *srval_a, int *srval_b) +{ + static const int bits[] = { + /* 0*/ SRVAL_B|14, INIT_A|14, 0, SRVAL_A|14, INIT_B|13, 0, SRVAL_B|13, INIT_A|13, + INIT_B|15, 0, SRVAL_B|15, INIT_A|15, 0, SRVAL_A|15, INIT_B|14, 0, + /*16*/ INIT_B|17, 0, SRVAL_B|17, INIT_A|17, 0, SRVAL_A|17, INIT_B|11, 0, + SRVAL_A|13, 0, INIT_B|12, 0, SRVAL_B|12, 0, INIT_A|12, SRVAL_A|12, + /*32*/ INIT_A|10, SRVAL_A|10, INIT_B|9, 0, 0, SRVAL_B|9, INIT_A|9, SRVAL_A|9, + SRVAL_B|11, INIT_A|11, 0, SRVAL_A|11, 0, INIT_B|10, 0, SRVAL_B|10, + /*48*/ 0, 0, 0, 0, 0, 0, 0, 0, + INIT_B|8, 0, SRVAL_B|8, INIT_A|8, 0, SRVAL_A|8, 0, 0, + /*64*/ 0, INIT_B|7, SRVAL_B|7, INIT_A|7, 0, SRVAL_A|7, 0, INIT_B|6, + 0, 0, 0, 0, 0, 0, 0, 0, + /*80*/ 0, SRVAL_A|5, INIT_B|4, 0, 0, SRVAL_B|4, INIT_A|4, SRVAL_A|4, + SRVAL_B|6, INIT_A|6, 0, SRVAL_A|6, INIT_B|5, 0, SRVAL_B|5, INIT_A|5, + /*96*/ SRVAL_B|3, INIT_A|3, 0, SRVAL_A|3, 0, INIT_B|2, 0, SRVAL_B|2, + INIT_B|16, 0, SRVAL_B|16, INIT_A|16, 0, SRVAL_A|16, 0, INIT_B|3, + /*112*/ INIT_B|0, 0, SRVAL_B|0, INIT_A|0, 0, 0, SRVAL_A|0, 0, + INIT_A|2, SRVAL_A|2, 0, INIT_B|1, 0, SRVAL_B|1, INIT_A|1, SRVAL_A|1 }; + + int i, j, bit_set; + + *init_a = 0; *srval_a = 0; + *init_b = 0; *srval_b = 0; + for (i = 0; i < 8; i++) { + for (j = 0; j < 16; j++) { + if (!(eight_words->w[i] & (1< 17) + HERE(); + bit_set = 1<<(bits[i*16+j]&INIT_SRVAL_BITMASK); + if (bits[i*16+j] & INIT_A) { + *init_a |= bit_set; + } else if (bits[i*16+j] & SRVAL_A) { + *srval_a |= bit_set; + } else if (bits[i*16+j] & INIT_B) { + *init_b |= bit_set; + } else if (bits[i*16+j] & SRVAL_B) { + *srval_b |= bit_set; + } else { + HERE(); + } + } + } +} + +static void extract_init_srval_36(struct eight_words* eight_top_words, + struct eight_words* eight_bot_words, int64_t *init_a, + int64_t *init_b, int64_t *srval_a, int64_t *srval_b) +{ + int init_a_top, init_a_bot, srval_a_top, srval_a_bot, + init_b_top, init_b_bot, srval_b_top, srval_b_bot; + + extract_init_srval_18(eight_top_words, &init_a_top, &init_b_top, &srval_a_top, &srval_b_top); + extract_init_srval_18(eight_bot_words, &init_a_bot, &init_b_bot, &srval_a_bot, &srval_b_bot); + + *init_a = ((int64_t) init_a_top & 0xFFFF) | (((int64_t) init_a_bot & 0xFFFF) << 16) + | (((int64_t) init_a_top & 0x3000) << 32) | (( (int64_t) init_a_bot & 0x3000) << 34); + *init_b = ((int64_t) init_b_top & 0xFFFF) | (((int64_t) init_b_bot & 0xFFFF) << 16) + | (((int64_t) init_b_top & 0x3000) << 32) | (( (int64_t) init_b_bot & 0x3000) << 34); + *srval_a = ((int64_t) srval_a_top & 0xFFFF) | (((int64_t) srval_a_bot & 0xFFFF) << 16) + | (((int64_t) srval_a_top & 0x3000) << 32) | (( (int64_t) srval_a_bot & 0x3000) << 34); + *srval_b = ((int64_t) srval_b_top & 0xFFFF) | (((int64_t) srval_b_bot & 0xFFFF) << 16) + | (((int64_t) srval_b_top & 0x3000) << 32) | (( (int64_t) srval_b_bot & 0x3000) << 34); +} + +static int extract_bram(struct extract_state *es) +{ + RC_CHECK(es->model); +/* +typedef struct _bram_init // only first half of array used for bram8 +{ + int data[64][16]; + int parity[8][16]; +} bram_init_t; +void bram_extract_init(bram_init_t *init, const uint8_t *bits); + for (row = 3; row >= 0; row--) { + for (i = XC6_BRAM16_DEVS_PER_ROW-1; i >= 0; i--) { + printf_ramb_data(&cfg->bits.d[BRAM_DATA_START + + (row*XC6_BRAM16_DEVS_PER_ROW+i) + *XC6_BRAM_DATA_FRAMES_PER_DEV*FRAME_SIZE], + row, i); + } + } +*/ + // todo + RC_RETURN(es->model); +} + +static int write_bram(struct fpga_bits *bits, struct fpga_model *model) +{ + RC_CHECK(model); + // todo + RC_RETURN(model); +} + int extract_model(struct fpga_model* model, struct fpga_bits* bits) { struct extract_state es; @@ -2415,6 +2658,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) if (rc) { RC_SET(model, rc); goto out; } rc = extract_bscan(&es); if (rc) { RC_SET(model, rc); goto out; } + rc = extract_bram(&es); + if (rc) { RC_SET(model, rc); goto out; } // turn switches into nets if (model->nets) @@ -3188,6 +3433,7 @@ int write_model(struct fpga_bits *bits, struct fpga_model *model) write_type2(bits, model); write_logic(bits, model); write_bscan(bits, model); + write_bram(bits, model); RC_RETURN(model); } diff --git a/libs/bit_regs.c b/libs/bit_regs.c index e7ff3e4..040f63c 100644 --- a/libs/bit_regs.c +++ b/libs/bit_regs.c @@ -680,200 +680,12 @@ static int dump_maj_logic(const uint8_t* bits, int row, int major) return 0; } -#if 0 - -typedef struct ramb16_cfg -{ - uint8_t byte[64]; -} __attribute((packed)) ramb16_cfg_t; - -static const cfg_atom_t ramb16_instance = -{ - {-1}, {12,13, 274,275,276,277,316,317,318,319, - 420,421,422,423,-1}, "default_bits" -}; - -static cfg_atom_t ramb16_atoms[] = -{ - // data_width_a - {{264,265,260,261,256,257,-1},{ -1},"data_width_a 1"}, - {{264,265,260,261, -1},{ 256,257,-1},"data_width_a 2"}, - {{264,265, 256,257,-1},{ 260,261, -1},"data_width_a 4"}, - {{264,265, -1},{ 260,261,256,257,-1},"data_width_a 9"}, - {{ 260,261,256,257,-1},{264,265, -1},"data_width_a 18"}, - {{ 260,261, -1},{264,265, 256,257,-1},"data_width_a 36"}, - {{ -1},{264,265,260,261,256,257,-1},"data_width_a 0"}, - - // data_width_b - {{262,263,286,287,258,259,-1},{ -1},"data_width_b 1"}, - {{262,263,286,287, -1},{ 258,259,-1},"data_width_b 2"}, - {{262,263, 258,259,-1},{ 286,287, -1},"data_width_b 4"}, - {{262,263, -1},{ 286,287,258,259,-1},"data_width_b 9"}, - {{ 286,287,258,259,-1},{262,263, -1},"data_width_b 18"}, - {{ 286,287, -1},{262,263, 258,259,-1},"data_width_b 36"}, - {{ -1},{262,263,286,287,258,259,-1},"data_width_b 0"}, - - // required - { { -1}, {266, 267, -1}, "RST_PRIORITY_B:CE" }, - { {266, 267, -1}, { -1}, "RST_PRIORITY_B:SR" }, - { { -1}, {268, 269, -1}, "RST_PRIORITY_A:CE" }, - { {268, 269, -1}, { -1}, "RST_PRIORITY_A:SR" }, - { { -1}, {290, 291, -1}, "EN_RSTRAM_A:TRUE" }, - { {290, 291, -1}, { -1}, "EN_RSTRAM_A:FALSE" }, - { { -1}, {444, 445, -1}, "EN_RSTRAM_B:TRUE" }, - { {444, 445, -1}, { -1}, "EN_RSTRAM_B:FALSE" }, - - // optional - { { -1}, { 26, 27, -1}, "CLKAINV:CLKA" }, - { { 26, 27, -1}, { -1}, "CLKAINV:CLKA_B" }, // def - { { -1}, { 30, 31, -1}, "CLKBINV:CLKB" }, - { { 30, 31, -1}, { -1}, "CLKBINV:CLKB_B" }, // def - { { -1}, {270, 271, -1}, "RSTTYPE:ASYNC" }, - { {270, 271, -1}, { -1}, "RSTTYPE:SYNC" }, // def - { { -1}, {278, 279, -1}, "WRITE_MODE_B:READ_FIRST" }, - { { -1}, {280, 281, -1}, "WRITE_MODE_A:READ_FIRST" }, - { { -1}, {282, 283, -1}, "WRITE_MODE_B:NO_CHANGE" }, - { { -1}, {284, 285, -1}, "WRITE_MODE_A:NO_CHANGE" }, - { {278, 279, 282, 283, -1}, {-1}, "WRITE_MODE_B:WRITE_FIRST" }, //def - { {280, 281, 284, 285, -1}, {-1}, "WRITE_MODE_A:WRITE_FIRST" }, //def - { { -1}, {306, 307, -1}, "DOB_REG:1" }, - { {306, 306, -1}, { -1}, "DOB_REG:0" }, // def - { { -1}, {308, 309, -1}, "DOA_REG:1" }, - { {308, 309, -1}, { -1}, "DOA_REG:0" }, // def - { {431, 467, -1}, {430, 466, -1}, "ENAINV:ENA" }, // def - { {430, 431, 466, 467, -1}, {-1}, "ENAINV:ENA_B" }, - { {465, 469, -1}, {464, 468, -1}, "ENBINV:ENB" }, // def - { {464, 465, 468, 469, -1}, {-1}, "ENBINV:ENB_B" }, - { { -1}, { 20, 21, -1}, "REGCEAINV:REGCEA" }, // def - { { 20, 21, -1}, { -1}, "REGCEAINV:REGCEA_B" }, - { { -1}, { 8, 9, -1}, "REGCEBINV:REGCEB" }, - { { 8, 9, -1}, { -1}, "REGCEBINV:REGCEB_B" }, // def - { { 24, 25, -1}, { -1}, "RSTAINV:RSTA" }, // def - { { -1}, { 24, 25, -1}, "RSTAINV:RSTA_B" }, - { { -1}, { 4, 5, -1}, "RSTBINV:RSTB" }, // def - { { 4, 5, -1}, { -1}, "RSTBINV:RSTB_B" }, - { { -1}, { 19, -1}, "WEA0INV:WEA0" }, // def - { { 19, -1}, { -1}, "WEA0INV:WEA0_B" }, - { { -1}, { 23, -1}, "WEA2INV:WEA1" }, // def - { { 23, -1}, { -1}, "WEA2INV:WEA1_B" }, - { { -1}, { 18, -1}, "WEA2INV:WEA2" }, // def - { { 18, -1}, { -1}, "WEA2INV:WEA2_B" }, - { { -1}, { 22, -1}, "WEA2INV:WEA3" }, // def - { { 22, -1}, { -1}, "WEA2INV:WEA3_B" }, - { { -1}, { 7, -1}, "WEB0INV:WEB0" }, // def - { { 7, -1}, { -1}, "WEB0INV:WEB0_B" }, - { { -1}, { 3, -1}, "WEB1INV:WEB1" }, // def - { { 3, -1}, { -1}, "WEB1INV:WEB1_B" }, - { { -1}, { 6, -1}, "WEB2INV:WEB2" }, // def - { { 6, -1}, { -1}, "WEB2INV:WEB2_B" }, - { { -1}, { 2, -1}, "WEB3INV:WEB3" }, // def - { { 2, -1}, { -1}, "WEB3INV:WEB3_B" }, -}; - -static void print_ramb16_cfg(ramb16_cfg_t* cfg) -{ - char bits[512]; - uint8_t u8; - int i, first_extra; - - for (i = 0; i < 32; i++) { - u8 = cfg->byte[i*2]; - cfg->byte[i*2] = cfg->byte[i*2+1]; - cfg->byte[i*2+1] = u8; - } - for (i = 0; i < 64; i++) { - u8 = 0; - if (cfg->byte[i] & 0x01) u8 |= 0x80; - if (cfg->byte[i] & 0x02) u8 |= 0x40; - if (cfg->byte[i] & 0x04) u8 |= 0x20; - if (cfg->byte[i] & 0x08) u8 |= 0x10; - if (cfg->byte[i] & 0x10) u8 |= 0x08; - if (cfg->byte[i] & 0x20) u8 |= 0x04; - if (cfg->byte[i] & 0x40) u8 |= 0x02; - if (cfg->byte[i] & 0x80) u8 |= 0x01; - cfg->byte[i] = u8; - } - - // - // Bits 0..255 come from minor 23, Bits 256..511 from minor 24. - // Each set of 256 bits is divided into two halfs of 128 bits - // that are swept forward and backward to form 2-bit pairs, - // pairs 0..127 are formed out of bits 0..127 and 255..128, - // p128..p255 are formed out of b256..b383 and b511..b384. - // Since so much bit twiddling is already happening, we are sorting - // the bits so that pairs are next to each other. - // The notation for a pair is "p8=01". - - // minor 23 - for (i = 0; i < 128; i++) { - bits[i*2] = (cfg->byte[i/8] & (1<<(i%8))) != 0; - bits[i*2+1] = (cfg->byte[(255-i)/8] - & (1<<(7-(i%8)))) != 0; - } - // minor 24 - for (i = 0; i < 128; i++) { - bits[256+i*2] = (cfg->byte[32+i/8] & (1<<(i%8))) != 0; - bits[256+i*2+1] = (cfg->byte[32+(255-i)/8] - & (1<<(7-(i%8)))) != 0; - } - - printf("{\n"); - // hexdump(1 /* indent */, &cfg->byte[0], 64 /* len */); - for (i = 0; i < sizeof(ramb16_atoms)/sizeof(ramb16_atoms[0]); i++) { - if (atom_found(bits, &ramb16_atoms[i]) - && ramb16_atoms[i].must_1[0] != -1) { - printf(" %s\n", ramb16_atoms[i].str); - ramb16_atoms[i].flag = 1; - } else - ramb16_atoms[i].flag = 0; - } - for (i = 0; i < sizeof(ramb16_atoms)/sizeof(ramb16_atoms[0]); i++) { - if (ramb16_atoms[i].flag) - atom_remove(bits, &ramb16_atoms[i]); - } - // instantiation bits - if (ramb16_instance.must_1[0] != -1) { - if (atom_found(bits, &ramb16_instance)) { - for (i = 0; ramb16_instance.must_1[i] != -1; i++) - printf(" b%i\n", ramb16_instance.must_1[i]); - atom_remove(bits, &ramb16_instance); - } else - printf(" #W Not all instantiation bits set.\n"); - } - // extra bits - first_extra = 1; - for (i = 0; i < 512; i++) { - if (bits[i]) { - if (first_extra) { - printf(" #W Extra bits set.\n"); - first_extra = 0; - } - printf(" b%i\n", i); - } - } - printf("}\n"); -} -#endif - static void printf_minor_diff(int row, int major, int minor, const uint8_t *old_minor_bits, const uint8_t *new_minor_bits) { int word_i, w_old, w_new; char v16_str[32]; - // print words as pins (fpga bit ordering) - for (word_i = 0; word_i < FRAME_SIZE/XC6_WORD_BYTES; word_i++) { - if (word_i == XC6_HCLK_POS/XC6_WORD_BYTES) - sprintf(v16_str, "v16_clk"); - else - sprintf(v16_str, "v16_%i", - word_ir%i ma%i %s mi%i pin %s", row, major, v16_str, minor, fmt_word(w_new)); - } // print words as bits (cpu bit ordering) for (word_i = 0; word_i < FRAME_SIZE/XC6_WORD_BYTES; word_i++) { if (word_i == XC6_HCLK_POS/XC6_WORD_BYTES) @@ -881,11 +693,11 @@ static void printf_minor_diff(int row, int major, int minor, else sprintf(v16_str, "v16_%i", word_ir%i ma%i %s mi%i cpu %s", row, major, v16_str, minor, fmt_word(pinword_to_cpu(w_new))); + printf("#I r%i ma%i %s mi%i %s", row, major, v16_str, minor, fmt_word(w_new)); } } @@ -895,20 +707,6 @@ static void printf_minors(int row, int major, int minor, int num_minors, int word_i, minor_i, w; char v16_str[32]; - // print words as pins (fpga bit ordering) - for (word_i = 0; word_i < FRAME_SIZE/XC6_WORD_BYTES; word_i++) { - if (word_i == XC6_HCLK_POS/XC6_WORD_BYTES) - sprintf(v16_str, "v16_clk"); - else - sprintf(v16_str, "v16_%i", - word_i= 64) - offset_in_frame += 2; - for (j = 0; j < 32; j++) { - ramb16_cfg[i].byte[j] = bits[23*130+offset_in_frame+j]; - ramb16_cfg[i].byte[j+32] = bits[24*130+offset_in_frame+j]; - } - } - for (i = 0; i < 4; i++) { - for (j = 0; j < 64; j++) { - if (ramb16_cfg[i].byte[j]) - break; - } - if (j >= 64) - continue; - printf("r%i ma%i ramb16 i%i\n", - row, major, i); - print_ramb16_cfg(&ramb16_cfg[i]); - } -#endif return 0; } diff --git a/libs/control.c b/libs/control.c index 00bb0aa..f426ea9 100644 --- a/libs/control.c +++ b/libs/control.c @@ -2319,19 +2319,20 @@ static void fprintf_inout_pin(FILE* f, struct fpga_model* model, fprintf(f, "%s", buf); } -void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i) +void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i, int no_json) { struct fpga_net* net; int i, first_line; net = fnet_get(model, net_i); if (!net) { HERE(); return; } - fprintf(f, "[\n"); + if (!no_json) fprintf(f, "[\n"); first_line = 1; for (i = 0; i < net->len; i++) { if (!first_line) fprintf(f, ",\n"); first_line = 0; + if (no_json) fprintf(f, "net_i %i:", net_i); if (net->el[i].idx & NET_IDX_IS_PINW) { fprintf_inout_pin(f, model, net_i, &net->el[i]); continue; @@ -2342,7 +2343,8 @@ void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i) fpga_switch_print_json(model, net->el[i].y, net->el[i].x, net->el[i].idx)); } - fprintf(f, "\n ]"); + fprintf(f, "\n"); + if (!no_json) fprintf(f, " ]"); } // diff --git a/libs/control.h b/libs/control.h index ba88dd8..c95305d 100644 --- a/libs/control.h +++ b/libs/control.h @@ -410,7 +410,7 @@ int fnet_add_sw(struct fpga_model* model, net_idx_t net_i, int fnet_remove_sw(struct fpga_model* model, net_idx_t net_i, int y, int x, const swidx_t* switches, int num_sw); int fnet_remove_all_sw(struct fpga_model* model, net_idx_t net_i); -void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i); +void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i, int no_json); int fnet_route(struct fpga_model* model, net_idx_t net_i); // is_vcc == 1 for a vcc net, is_vcc == 0 for a gnd net diff --git a/libs/floorplan.c b/libs/floorplan.c index 33cc2c7..2b9b27a 100644 --- a/libs/floorplan.c +++ b/libs/floorplan.c @@ -11,8 +11,8 @@ #include "control.h" #include "floorplan.h" -#define PRINT_FLAG(fp, flag) if ((tf) & (flag)) \ - { fprintf (fp, " %s", #flag); tf &= ~(flag); } +#define PRINT_FLAG(fp, flag, firstp) if ((tf) & (flag)) \ + { fprintf (fp, "%s\"%s\"", firstp ? "" : ", ", #flag); tf &= ~(flag); firstp = 0; } void printf_version(FILE* f) { @@ -22,43 +22,53 @@ void printf_version(FILE* f) int printf_tiles(FILE* f, struct fpga_model* model) { struct fpga_tile* tile; - int x, y; + int x, y, first_line; RC_CHECK(model); + fprintf(f, " \"tiles\" : [\n"); for (x = 0; x < model->x_width; x++) { - fprintf(f, "\n"); + if (x) fprintf(f, ",\n\n"); + first_line = 1; for (y = 0; y < model->y_height; y++) { tile = &model->tiles[y*model->x_width + x]; - if (tile->type != NA) - fprintf(f, "tile y%i x%i name %s\n", y, x, + if (tile->type != NA) { + fprintf(f, "%s { \"y\" : %i, \"x\" : %i, \"name\" : \"%s\" }", + first_line ? "" : ",\n", y, x, fpga_tiletype_str(tile->type)); + first_line = 0; + } if (tile->flags) { - int tf = tile->flags; - fprintf(f, "tile y%i x%i flags", y, x); + int tf = tile->flags, first_flag = 1; + + fprintf(f, "%s { \"y\" : %i, \"x\" : %i, \"flags\" : [ ", + first_line ? "" : ",\n", y, x); + first_line = 0; - PRINT_FLAG(f, TF_FABRIC_ROUTING_COL); - PRINT_FLAG(f, TF_FABRIC_LOGIC_XM_COL); - PRINT_FLAG(f, TF_FABRIC_LOGIC_XL_COL); - PRINT_FLAG(f, TF_FABRIC_BRAM_VIA_COL); - PRINT_FLAG(f, TF_FABRIC_MACC_VIA_COL); - PRINT_FLAG(f, TF_FABRIC_BRAM_COL); - PRINT_FLAG(f, TF_FABRIC_MACC_COL); - PRINT_FLAG(f, TF_ROUTING_NO_IO); - PRINT_FLAG(f, TF_BRAM_DEV); - PRINT_FLAG(f, TF_MACC_DEV); - PRINT_FLAG(f, TF_LOGIC_XL_DEV); - PRINT_FLAG(f, TF_LOGIC_XM_DEV); - PRINT_FLAG(f, TF_IOLOGIC_DELAY_DEV); - PRINT_FLAG(f, TF_DCM_DEV); - PRINT_FLAG(f, TF_PLL_DEV); - PRINT_FLAG(f, TF_WIRED); + PRINT_FLAG(f, TF_FABRIC_ROUTING_COL, first_flag); + PRINT_FLAG(f, TF_FABRIC_LOGIC_XM_COL, first_flag); + PRINT_FLAG(f, TF_FABRIC_LOGIC_XL_COL, first_flag); + PRINT_FLAG(f, TF_FABRIC_BRAM_VIA_COL, first_flag); + PRINT_FLAG(f, TF_FABRIC_MACC_VIA_COL, first_flag); + PRINT_FLAG(f, TF_FABRIC_BRAM_COL, first_flag); + PRINT_FLAG(f, TF_FABRIC_MACC_COL, first_flag); + PRINT_FLAG(f, TF_ROUTING_NO_IO, first_flag); + PRINT_FLAG(f, TF_BRAM_DEV, first_flag); + PRINT_FLAG(f, TF_MACC_DEV, first_flag); + PRINT_FLAG(f, TF_LOGIC_XL_DEV, first_flag); + PRINT_FLAG(f, TF_LOGIC_XM_DEV, first_flag); + PRINT_FLAG(f, TF_IOLOGIC_DELAY_DEV, first_flag); + PRINT_FLAG(f, TF_DCM_DEV, first_flag); + PRINT_FLAG(f, TF_PLL_DEV, first_flag); + PRINT_FLAG(f, TF_WIRED, first_flag); + PRINT_FLAG(f, TF_CENTER_MIDBUF, first_flag); - if (tf) fprintf(f, " 0x%x", tf); - fprintf(f, "\n"); + if (tf) fprintf(f, "%s\"0x%x\"", first_flag ? "" : ", ", tf); + fprintf(f, " ] }"); } } } + fprintf(f, "\n ]"); return 0; } @@ -907,42 +917,51 @@ int printf_BUFGMUX(FILE *f, struct fpga_model *model, struct fpga_tile *tile; struct fpgadev_bufgmux *cfg; char pref[256]; - int dev_i; + int dev_i, first_line; dev_i = fpga_dev_idx(model, y, x, DEV_BUFGMUX, type_idx); RC_ASSERT(model, dev_i != NO_DEV); tile = YX_TILE(model, y, x); if (config_only && !(tile->devs[dev_i].instantiated)) RC_RETURN(model); - snprintf(pref, sizeof(pref), "dev y%i x%i BUFGMUX %i", y, x, type_idx); + snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"BUFGMUX\", \"dev_idx\" : %i", y, x, type_idx); + first_line = 1; - if (!config_only) - fprintf(f, "%s\n", pref); + if (!config_only) { + fprintf(f, "%s }", pref); + first_line = 0; + } cfg = &tile->devs[dev_i].u.bufgmux; switch (cfg->clk) { case BUFG_CLK_ASYNC: - fprintf(f, "%s clk ASYNC\n", pref); + fprintf(f, "%s%s, \"clk\" : \"ASYNC\" }", first_line ? "" : ",\n", pref); + first_line = 0; break; case BUFG_CLK_SYNC: - fprintf(f, "%s clk SYNC\n", pref); + fprintf(f, "%s%s, \"clk\" : \"SYNC\" }", first_line ? "" : ",\n", pref); + first_line = 0; break; case 0: break; default: RC_FAIL(model, EINVAL); } switch (cfg->disable_attr) { case BUFG_DISATTR_LOW: - fprintf(f, "%s disable_attr LOW\n", pref); + fprintf(f, "%s%s, \"disable_attr\" : \"LOW\" }", first_line ? "" : ",\n", pref); + first_line = 0; break; case BUFG_DISATTR_HIGH: - fprintf(f, "%s disable_attr HIGH\n", pref); + fprintf(f, "%s%s, \"disable_attr\" : \"HIGH\" }", first_line ? "" : ",\n", pref); + first_line = 0; break; case 0: break; default: RC_FAIL(model, EINVAL); } switch (cfg->s_inv) { case BUFG_SINV_N: - fprintf(f, "%s s_inv NO\n", pref); + fprintf(f, "%s%s, \"s_inv\" : false }", first_line ? "" : ",\n", pref); + first_line = 0; break; case BUFG_SINV_Y: - fprintf(f, "%s s_inv YES\n", pref); + fprintf(f, "%s%s, \"s_inv\" : true }", first_line ? "" : ",\n", pref); + first_line = 0; break; case 0: break; default: RC_FAIL(model, EINVAL); } @@ -990,35 +1009,44 @@ int printf_BUFIO(FILE *f, struct fpga_model *model, struct fpga_tile *tile; struct fpgadev_bufio *cfg; char pref[256]; - int dev_i; + int dev_i, first_line; dev_i = fpga_dev_idx(model, y, x, DEV_BUFIO, type_idx); RC_ASSERT(model, dev_i != NO_DEV); tile = YX_TILE(model, y, x); if (config_only && !(tile->devs[dev_i].instantiated)) RC_RETURN(model); - snprintf(pref, sizeof(pref), "dev y%i x%i BUFIO %i", y, x, type_idx); + snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"BUFIO\", \"dev_idx\" : %i", y, x, type_idx); + first_line = 1; - if (!config_only) - fprintf(f, "%s\n", pref); + if (!config_only) { + fprintf(f, "%s }", pref); + first_line = 0; + } cfg = &tile->devs[dev_i].u.bufio; - if (cfg->divide) - fprintf(f, "%s divide %i\n", pref, cfg->divide); + if (cfg->divide) { + fprintf(f, "%s%s, \"divide\" : %i\n", first_line ? "" : ",\n", pref, cfg->divide); + first_line = 0; + } switch (cfg->divide_bypass) { case BUFIO_DIVIDEBP_N: - fprintf(f, "%s divide_bypass NO\n", pref); + fprintf(f, "%s%s, \"divide_bypass\" : false }", first_line ? "" : ",\n", pref); + first_line = 0; break; case BUFIO_DIVIDEBP_Y: - fprintf(f, "%s divide_bypass YES\n", pref); + fprintf(f, "%s%s, \"divide_bypass\" : true }", first_line ? "" : ",\n", pref); + first_line = 0; break; case 0: break; default: RC_FAIL(model, EINVAL); } switch (cfg->i_inv) { case BUFIO_IINV_N: - fprintf(f, "%s i_inv NO\n", pref); + fprintf(f, "%s%s, \"i_inv\" : false }", first_line ? "" : ",\n", pref); + first_line = 0; break; case BUFIO_IINV_Y: - fprintf(f, "%s i_inv YES\n", pref); + fprintf(f, "%s%s, \"i_inv\" : true }", first_line ? "" : ",\n", pref); + first_line = 0; break; case 0: break; default: RC_FAIL(model, EINVAL); } @@ -1062,26 +1090,33 @@ int printf_BSCAN(FILE *f, struct fpga_model *model, struct fpga_tile *tile; struct fpgadev_bscan *cfg; char pref[256]; - int dev_i; + int dev_i, first_line; dev_i = fpga_dev_idx(model, y, x, DEV_BSCAN, type_idx); RC_ASSERT(model, dev_i != NO_DEV); tile = YX_TILE(model, y, x); if (config_only && !(tile->devs[dev_i].instantiated)) RC_RETURN(model); - snprintf(pref, sizeof(pref), "dev y%i x%i BSCAN %i", y, x, type_idx); + snprintf(pref, sizeof(pref), " { \"y\" : %i, \"x\" : %i, \"dev\" : \"BSCAN\", \"dev_idx\" : %i", y, x, type_idx); + first_line = 1; - if (!config_only) - fprintf(f, "%s\n", pref); + if (!config_only) { + fprintf(f, "%s }", pref); + first_line = 0; + } cfg = &tile->devs[dev_i].u.bscan; - if (cfg->jtag_chain) - fprintf(f, "%s jtag_chain %i\n", pref, cfg->jtag_chain); + if (cfg->jtag_chain) { + fprintf(f, "%s%s, \"jtag_chain\" : %i }", first_line ? "" : ",\n", pref, cfg->jtag_chain); + first_line = 0; + } switch (cfg->jtag_test) { case BSCAN_JTAG_TEST_N: - fprintf(f, "%s jtag_test NO\n", pref); + fprintf(f, "%s%s, \"jtag_test\" : false }", first_line ? "" : ",\n", pref); + first_line = 0; break; case BSCAN_JTAG_TEST_Y: - fprintf(f, "%s jtag_test YES\n", pref); + fprintf(f, "%s%s, \"jtag_test\" : true }", first_line ? "" : ",\n", pref); + first_line = 0; break; case 0: break; default: RC_FAIL(model, EINVAL); } @@ -1111,13 +1146,13 @@ inst: return 2; } -int printf_devices(FILE* f, struct fpga_model* model, int config_only) +int printf_devices(FILE* f, struct fpga_model* model, int config_only, int no_json) { int x, y, i, first_dev; struct fpga_tile* tile; RC_CHECK(model); - fprintf(f, " \"devices\" : [\n"); + if (!no_json) fprintf(f, " \"devices\" : [\n"); first_dev = 1; for (x = 0; x < model->x_width; x++) { for (y = 0; y < model->y_height; y++) { @@ -1163,7 +1198,7 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only) } } if (!first_dev) fprintf(f, "\n"); - fprintf(f, " ]"); + if (!no_json) fprintf(f, " ]"); RC_RETURN(model); } @@ -1172,14 +1207,16 @@ int printf_ports(FILE* f, struct fpga_model* model) struct fpga_tile* tile; const char* conn_point_name_src; int x, y, i, conn_point_dests_o, num_dests_for_this_conn_point; - int first_port_printed; + int first_in_tile, first_tile; RC_CHECK(model); + fprintf(f, " \"ports\" : [\n"); + first_tile = 1; for (x = 0; x < model->x_width; x++) { for (y = 0; y < model->y_height; y++) { tile = &model->tiles[y*model->x_width + x]; - first_port_printed = 0; + first_in_tile = 1; 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) @@ -1195,16 +1232,17 @@ int printf_ports(FILE* f, struct fpga_model* model) tile->conn_point_names[i*2+1], x, y, i); continue; } - if (!first_port_printed) { - first_port_printed = 1; - fprintf(f, "\n"); - } - fprintf(f, "port y%i x%i %s\n", - y, x, conn_point_name_src); + if (first_in_tile && !first_tile) + fprintf(f, ",\n\n"); + fprintf(f, "%s { \"y\" : %i, \"x\" : %i, \"name\" : \"%s\" }", + first_in_tile ? "" : ",\n", y, x, conn_point_name_src); + first_in_tile = 0; + first_tile = 0; } } } - return 0; + fprintf(f, "\n ]"); + RC_RETURN(model); } int printf_conns(FILE* f, struct fpga_model* model) @@ -1214,14 +1252,16 @@ int printf_conns(FILE* f, struct fpga_model* model) const char* conn_point_name_src, *other_tile_connpt_str; uint16_t other_tile_connpt_str_i; 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; + int other_tile_x, other_tile_y, first_tile, first_in_tile; RC_CHECK(model); + fprintf(f, " \"connections\" : [\n"); + first_tile = 1; for (x = 0; x < model->x_width; x++) { for (y = 0; y < model->y_height; y++) { tile = &model->tiles[y*model->x_width + x]; - first_conn_printed = 0; + first_in_tile = 1; 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) @@ -1248,66 +1288,73 @@ int printf_conns(FILE* f, struct fpga_model* model) continue; } - if (!first_conn_printed) { - first_conn_printed = 1; - fprintf(f, "\n"); - } - sprintf(tmp_line, "conn y%i x%i %s ", + if (first_in_tile && !first_tile) + fprintf(f, ",\n\n"); + sprintf(tmp_line, "\"y1\" : %i, \"x1\" : %i, \"name1\" : \"%s\", ", y, x, conn_point_name_src); k = strlen(tmp_line); - while (k < 45) + while (k < 60) tmp_line[k++] = ' '; - sprintf(&tmp_line[k], "y%i x%i %s\n", + sprintf(&tmp_line[k], "\"y2\" : %i, \"x2\" : %i, \"name2\" : \"%s\"", other_tile_y, other_tile_x, other_tile_connpt_str); - fprintf(f, "%s", tmp_line); + fprintf(f, "%s { %s }", + first_in_tile ? "" : ",\n", tmp_line); + first_in_tile = 0; + first_tile = 0; } } } } - return 0; + fprintf(f, "\n ]"); + RC_RETURN(model); } -int printf_switches(FILE* f, struct fpga_model* model) +int printf_switches(FILE *f, struct fpga_model *model) { - struct fpga_tile* tile; - int x, y, i, first_switch_printed; + struct fpga_tile *tile; + int x, y, i, first_in_tile, first_tile; RC_CHECK(model); + fprintf(f, " \"switches\" : [\n"); + first_tile = 1; for (x = 0; x < model->x_width; x++) { for (y = 0; y < model->y_height; y++) { tile = YX_TILE(model, y, x); - first_switch_printed = 0; + first_in_tile = 1; for (i = 0; i < tile->num_switches; i++) { - if (!first_switch_printed) { - first_switch_printed = 1; - fprintf(f, "\n"); - } - fprintf(f, "sw y%i x%i %s\n", - y, x, fpga_switch_print(model, y, x, i)); + if (first_in_tile && !first_tile) + fprintf(f, ",\n\n"); + fprintf(f, "%s { \"y\" : %i, \"x\" : %i%s }", + first_in_tile ? "" : ",\n", y, x, + fpga_switch_print_json(model, y, x, i)); + first_in_tile = 0; + first_tile = 0; } } } - return 0; + fprintf(f, "\n ]"); + RC_RETURN(model); } -int printf_nets(FILE* f, struct fpga_model* model) +int printf_nets(FILE* f, struct fpga_model* model, int no_json) { net_idx_t net_i; int rc, first_line; RC_CHECK(model); - fprintf(f, " \"nets\" : [\n"); + if (!no_json) fprintf(f, " \"nets\" : [\n"); first_line = 1; net_i = NO_NET; while (!(rc = fnet_enum(model, net_i, &net_i)) && net_i != NO_NET) { - if (!first_line) - fprintf(f, ","); + if (!no_json) fprintf(f, first_line ? " " : ","); first_line = 0; - fnet_printf(f, model, net_i); + fnet_printf(f, model, net_i, no_json); } if (rc) FAIL(rc); - if (!first_line) fprintf(f, "\n"); - fprintf(f, " ]"); + if (!no_json) { + if (!first_line) fprintf(f, "\n"); + fprintf(f, " ]"); + } return 0; fail: return rc; @@ -1555,19 +1602,24 @@ int read_floorplan(struct fpga_model* model, FILE* f) int write_floorplan(FILE* f, struct fpga_model* model, int flags) { - fprintf(f, "{\n"); - printf_version(f); + if (!(flags & FP_NO_JSON)) { + fprintf(f, "{\n"); + printf_version(f); + } if (model->rc) fprintf(f, "rc %i\n", model->rc); else { - fprintf(f, ",\n"); - printf_devices(f, model, /*config_only*/ 1); + if (!(flags & FP_NO_JSON)) + fprintf(f, ",\n"); + printf_devices(f, model, /*config_only*/ 1, flags & FP_NO_JSON); - fprintf(f, ",\n"); - printf_nets(f, model); + if (!(flags & FP_NO_JSON)) + fprintf(f, ",\n"); + printf_nets(f, model, flags & FP_NO_JSON); } - fprintf(f, "\n}\n"); + if (!(flags & FP_NO_JSON)) + fprintf(f, "\n}\n"); RC_RETURN(model); } diff --git a/libs/floorplan.h b/libs/floorplan.h index fa65ce2..a45235c 100644 --- a/libs/floorplan.h +++ b/libs/floorplan.h @@ -7,16 +7,16 @@ int read_floorplan(struct fpga_model *model, FILE *f); #define FP_DEFAULT 0x0000 -#define FP_NO_HEADER 0x0001 +#define FP_NO_JSON 0x0001 int write_floorplan(FILE *f, struct fpga_model *model, int flags); void printf_version(FILE *f); int printf_tiles(FILE *f, struct fpga_model *model); -int printf_devices(FILE *f, struct fpga_model *model, int config_only); +int printf_devices(FILE *f, struct fpga_model *model, int config_only, int no_json); int printf_ports(FILE *f, struct fpga_model *model); int printf_conns(FILE *f, struct fpga_model *model); int printf_switches(FILE *f, struct fpga_model *model); -int printf_nets(FILE *f, struct fpga_model *model); +int printf_nets(FILE *f, struct fpga_model *model, int no_json); int printf_IOB(FILE* f, struct fpga_model* model, int y, int x, int type_idx, int config_only); diff --git a/libs/helper.c b/libs/helper.c index 4ba9044..98f108c 100644 --- a/libs/helper.c +++ b/libs/helper.c @@ -79,32 +79,41 @@ void dump_data(int indent, const uint8_t *data, int len, int base) } // returns a 16-bit word (0:15) plus 2 bits parity in bits 16 & 17 -static int get_ramb_word_with_parity(const void *d, int word_idx) +static int get_ramb_word_with_parity(const void *d, int word_idx, int clear_bits) { - int w, i, bit_pos; + int w, i, bit_pos, bit_mask; w = 0; for (i = 0; i < 16; i++) { bit_pos = word_idx * 18 + 2 + 15-i; - if (((uint8_t *)d)[bit_pos/8] & (1<<((7-(bit_pos%8))))) + bit_mask = 1<<((7-(bit_pos%8))); + if (((uint8_t *)d)[bit_pos/8] & bit_mask) w |= 1<> 24)); \ } -int atom_found(char *bits, const cfg_atom_t *atom) -{ - int i; - for (i = 0; atom->must_0[i] != -1; i++) - if (bits[atom->must_0[i]]) - break; - if (atom->must_0[i] != -1) - return 0; - for (i = 0; atom->must_1[i] != -1; i++) - if (!bits[atom->must_1[i]]) - break; - return atom->must_1[i] == -1; -} - -void atom_remove(char *bits, const cfg_atom_t *atom) -{ - int i; - for (i = 0; atom->must_1[i] != -1; i++) { - if (bits[atom->must_1[i]]) - bits[atom->must_1[i]] = 0; - } -} - static int bool_nextlen(const char *expr, int len) { int i, depth; @@ -471,53 +457,14 @@ void printf_type2(uint8_t *d, int len, int inpos, int num_entries) } } -static int ramb_words_to_bram16(int (*init_data)[64][16], int (*init_parity)[8][16], int (*ramb_words)[1024]) +static void ramb_words_split_data_parity(const int (*ramb_words)[1024], + int (*init_data)[64][16], int (*init_parity)[8][16]) { - int init_i, i, j, bits_set; + int init_i, i, j; - bits_set = 0; - // prepare parity words for string printf + // merge parity bits into parity words for (init_i = 0; init_i < 8; init_i++) { - for (i = 0; i < 16; i++) { // 16 uint16_t words in one ramb16 parity string - (*init_parity)[init_i][i] = 0; - // 2 parity bits from each word, so 2*4=8 words have - // to be processed for 16 parity bits - for (j = 0; j < 4; j++) { - if ((*ramb_words)[64*init_i + 4*i + j] & (1<<16)) - (*init_parity)[init_i][i] |= 1<<(j*4+0); - if ((*ramb_words)[64*init_i + 4*i + j] & (1<<17)) - (*init_parity)[init_i][i] |= 1<<(j*4+1); - if ((*ramb_words)[512 + 64*init_i + 4*i + j] & (1<<16)) - (*init_parity)[init_i][i] |= 1<<(j*4+2); - if ((*ramb_words)[512 + 64*init_i + 4*i + j] & (1<<17)) - (*init_parity)[init_i][i] |= 1<<(j*4+3); - } - if ((*init_parity)[init_i][i]) - bits_set = 1; - } - } - // prepare data words for string printf - for (init_i = 0; init_i < 64; init_i++) { - for (i = 0; i < 8; i++) { - (*init_data)[init_i][i*2] = (*ramb_words)[init_i*8 + i] & 0xFFFF; - (*init_data)[init_i][i*2+1] = (*ramb_words)[512 + init_i*8 + i] & 0xFFFF; - - if ((*init_data)[init_i][i*2] - || (*init_data)[init_i][i*2+1]) - bits_set = 1; - } - } - return bits_set; -} - -static int ramb_words_to_bram8(int (*init_data)[64][16], int (*init_parity)[8][16], int (*ramb_words)[1024]) -{ - int init_i, i, j, devs_used; - - devs_used = 0; // bit1 = dev0, bit2 = dev1 - // prepare parity words (0:3 are for the first bram8 device, 4:7 for the second one) - for (init_i = 0; init_i < 8; init_i++) { - for (i = 0; i < 16; i++) { // 16 uint16_t words in one ramb16 parity string + for (i = 0; i < 16; i++) { (*init_parity)[init_i][i] = 0; // 2 parity bits from each word, so 2*4=8 words have // to be processed for 16 parity bits @@ -527,26 +474,21 @@ static int ramb_words_to_bram8(int (*init_data)[64][16], int (*init_parity)[8][1 if ((*ramb_words)[128*init_i + 8*i + j] & (1<<17)) (*init_parity)[init_i][i] |= 1<<(j*2+1); } - if ((*init_parity)[init_i][i]) - devs_used |= (init_i < 4) ? 0x01 : 0x02; } } - // prepare data words (0:31 are for the first bram8 device, 32:63 for the second one) + // mask out parity bits for (init_i = 0; init_i < 64; init_i++) { for (i = 0; i < 16; i++) { (*init_data)[init_i][i] = (*ramb_words)[init_i*16 + i] & 0xFFFF; - if ((*init_data)[init_i][i]) - devs_used |= (init_i < 32) ? 0x01 : 0x02; } } - return devs_used; } void printf_ramb_data(const uint8_t *bits, int row, int bram_idx) { int nonzero_head, nonzero_tail, ramb_words[1024]; int init_data[64][16], init_parity[8][16]; - int i, j, devs_used; + int i, j, header_printed; // check head and tail nonzero_head = 0; @@ -579,102 +521,123 @@ void printf_ramb_data(const uint8_t *bits, int row, int bram_idx) } } - ramb_data_to_words(ramb_words, &bits[18], sizeof(ramb_words)/sizeof(*ramb_words)); + ramb_data_to_words(ramb_words, &bits[XC6_BRAM_DATA_PREFIX_LEN], + sizeof(ramb_words)/sizeof(*ramb_words), /*clear_bits*/ 0); + ramb_words_split_data_parity(&ramb_words, &init_data, &init_parity); // ramb16 - devs_used = ramb_words_to_bram16(&init_data, &init_parity, &ramb_words); - if (devs_used) { - printf("br%i maj_i %i dev_i %i/16\n", row, - bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, - bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); - printf("{\n"); - for (i = 0; i < 8; i++) { - for (j = 0; j < 16; j++) { - if (init_parity[i][j]) { - printf(" parity 0x%02X \"", i); - for (j = 0; j < 16; j++) - printf("%04X", init_parity[i][15-j]); - printf("\"\n"); - break; - } + header_printed = 0; + for (i = 0; i < 8; i++) { + for (j = 0; j < 16; j++) { + if (!init_parity[i][j]) continue; + if (!header_printed) { + header_printed = 1; + printf("br%i maj_i %i dev_i %i/16\n{\n", row, + bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, + bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); } + printf(" parity 0x%02X \"", i); + for (j = 0; j < 16; j++) + printf("%04X", init_parity[i][15-j]); + printf("\"\n"); } - for (i = 0; i < 64; i++) { - for (j = 0; j < 16; j++) { - if (init_data[i][j]) { - printf(" init 0x%02X \"", i); - for (j = 0; j < 16; j++) - printf("%04X", init_data[i][15-j]); - printf("\"\n"); - break; - } - } - } - printf("}\n"); } + for (i = 0; i < 64; i++) { + for (j = 0; j < 16; j++) { + if (!init_data[i][j]) continue; + if (!header_printed) { + header_printed = 1; + printf("br%i maj_i %i dev_i %i/16\n{\n", row, + bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, + bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); + } + printf(" init 0x%02X \"", i); + for (j = 0; j < 16; j++) + printf("%04X", init_data[i][15-j]); + printf("\"\n"); + } + } + if (header_printed) + printf("}\n"); - devs_used = ramb_words_to_bram8(&init_data, &init_parity, &ramb_words); // ramb8,0 - if (devs_used & 0x01) { - printf("br%i maj_i %i dev_i %i,0/8\n", row, - bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, - bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); - printf("{\n"); - for (i = 0; i < 4; i++) { - for (j = 0; j < 16; j++) { - if (init_parity[i][j]) { - printf(" parity 0x%02X \"", i); - for (j = 0; j < 16; j++) - printf("%04X", init_parity[i][15-j]); - printf("\"\n"); - break; - } + header_printed = 0; + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + if (!init_parity[i][j]) continue; + if (!header_printed) { + header_printed = 1; + printf("br%i maj_i %i dev_i %i,0/8\n{\n", row, + bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, + bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); } + printf(" parity 0x%02X \"", i); + for (j = 0; j < 16; j++) + printf("%04X", init_parity[i][15-j]); + printf("\"\n"); } - for (i = 0; i < 32; i++) { - for (j = 0; j < 16; j++) { - if (init_data[i][j]) { - printf(" init 0x%02X \"", i); - for (j = 0; j < 16; j++) - printf("%04X", init_data[i][15-j]); - printf("\"\n"); - break; - } - } - } - printf("}\n"); } + for (i = 0; i < 32; i++) { + for (j = 0; j < 16; j++) { + if (!init_data[i][j]) continue; + if (!header_printed) { + header_printed = 1; + printf("br%i maj_i %i dev_i %i,0/8\n{\n", row, + bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, + bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); + } + printf(" init 0x%02X \"", i); + for (j = 0; j < 16; j++) + printf("%04X", init_data[i][15-j]); + printf("\"\n"); + } + } + if (header_printed) + printf("}\n"); // ramb8,1 - if (devs_used & 0x02) { - printf("br%i maj_i %i dev_i %i,1/8\n", row, - bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, - bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); - printf("{\n"); - for (i = 4; i < 8; i++) { - for (j = 0; j < 16; j++) { - if (init_parity[i][j]) { - printf(" parity 0x%02X \"", i-4); - for (j = 0; j < 16; j++) - printf("%04X", init_parity[i][15-j]); - printf("\"\n"); - break; - } + header_printed = 0; + for (i = 4; i < 8; i++) { + for (j = 0; j < 16; j++) { + if (!init_parity[i][j]) continue; + if (!header_printed) { + header_printed = 1; + printf("br%i maj_i %i dev_i %i,1/8\n{\n", row, + bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, + bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); } + printf(" parity 0x%02X \"", i-4); + for (j = 0; j < 16; j++) + printf("%04X", init_parity[i][15-j]); + printf("\"\n"); } - for (i = 32; i < 64; i++) { - for (j = 0; j < 16; j++) { - if (init_data[i][j]) { - printf(" init 0x%02X \"", i-32); - for (j = 0; j < 16; j++) - printf("%04X", init_data[i][15-j]); - printf("\"\n"); - break; - } - } - } - printf("}\n"); } + for (i = 32; i < 64; i++) { + for (j = 0; j < 16; j++) { + if (!init_data[i][j]) continue; + if (!header_printed) { + header_printed = 1; + printf("br%i maj_i %i dev_i %i,1/8\n{\n", row, + bram_idx/XC6_BRAM16_DEVS_PER_MAJOR, + bram_idx%XC6_BRAM16_DEVS_PER_MAJOR); + } + printf(" init 0x%02X \"", i-32); + for (j = 0; j < 16; j++) + printf("%04X", init_data[i][15-j]); + printf("\"\n"); + } + } + if (header_printed) + printf("}\n"); +} + +void bram_extract_init(bram_init_t *init, const uint8_t *bits) +{ + int ramb_words[1024]; + + ramb_data_to_words(ramb_words, &bits[XC6_BRAM_DATA_PREFIX_LEN], + sizeof(ramb_words)/sizeof(*ramb_words), /*clear_bits*/ 1); + ramb_words_split_data_parity(&ramb_words, &init->data, &init->parity); } int is_empty(const uint8_t *d, int l) @@ -718,6 +681,16 @@ void frame_set_bit(uint8_t *frame_d, int bit) frame_d[(bit/16)*2 + !((bit/8)%2)] |= v; } +int frame_get_cpuword(const void *bits) +{ + return mirror_2bytes(frame_get_pinword(bits)); +} + +void frame_set_cpuword(void *bits, int v) +{ + frame_set_pinword(bits, mirror_2bytes(v)); +} + // see ug380, table 2-5, bit ordering int frame_get_pinword(const void *bits) { @@ -727,7 +700,7 @@ int frame_get_pinword(const void *bits) return byte0 << 8 | byte1; } -void frame_set_pinword(void* bits, int v) +void frame_set_pinword(void *bits, int v) { ((uint8_t*)bits)[0] = v >> 8; ((uint8_t*)bits)[1] = v & 0xFF; @@ -742,9 +715,9 @@ uint8_t mirror_bits(uint8_t v) return mv; } -int pinword_to_cpu(int pinword) +int mirror_2bytes(int v) { - return mirror_bits(((pinword & 0xFF00) >> 8)) << 8 | mirror_bits(pinword & 0xFF); + return mirror_bits(((v & 0xFF00) >> 8)) << 8 | mirror_bits(v & 0xFF); } // see ug380, table 2-5, bit ordering @@ -1025,7 +998,7 @@ const char *fmt_word(int word) static char buf[NUM_BUFS][BUF_SIZE]; static int last_buf = 0; char bit_str[XC6_WORD_BITS]; - int i, num_bits_printed; + int i; last_buf = (last_buf+1)%NUM_BUFS; @@ -1033,16 +1006,11 @@ const char *fmt_word(int word) bit_str[i] = (word & (1ULL << (XC6_WORD_BITS-i-1))) ? '1' : '0'; snprintf(buf[last_buf], sizeof(*buf), "0b%.*s 0x%.*X", XC6_WORD_BITS, bit_str, XC6_WORD_BITS/4, word); - num_bits_printed = 0; for (i = 0; i < XC6_WORD_BITS; i++) { - if (word & (1 << i)) { - if (num_bits_printed >= 4) { - sprintf(&buf[last_buf][strlen(buf[last_buf])], " ..."); - break; - } + if (word & (1 << i)) sprintf(&buf[last_buf][strlen(buf[last_buf])], " %i", i); - num_bits_printed++; - } + else + sprintf(&buf[last_buf][strlen(buf[last_buf])], i < 10 ? " " : " "); } strcat(buf[last_buf], "\n"); return buf[last_buf]; diff --git a/libs/helper.h b/libs/helper.h index 02e690c..375bd3c 100644 --- a/libs/helper.h +++ b/libs/helper.h @@ -57,16 +57,13 @@ uint32_t __swab32(uint32_t x); #define ATOM_MAX_BITS 32+1 // -1 signals end of array -typedef struct _cfg_atom +typedef struct _cfg_bits { - int must_0[ATOM_MAX_BITS]; - int must_1[ATOM_MAX_BITS]; - const char* str; - int flag; // used to remember a state such as 'found' -} cfg_atom_t; - -int atom_found(char* bits, const cfg_atom_t* atom); -void atom_remove(char* bits, const cfg_atom_t* atom); + int minor; // -1 is illegal and can be used to signal end-of-array + int rel_v16; // vertical 16 from top, relative to start of device + int bits; // 1 or more bits set + int name; // enum value +} cfg_bits_t; uint64_t map_bits(uint64_t u64, int num_bits, int* src_pos); @@ -80,6 +77,13 @@ int bool_req_pins(uint64_t u64, int num_bits); void printf_type2(uint8_t* d, int len, int inpos, int num_entries); void printf_ramb_data(const uint8_t *bits, int row, int bram_idx); +typedef struct _bram_init // only first half of array used for bram8 +{ + int data[64][16]; + int parity[8][16]; +} bram_init_t; +void bram_extract_init(bram_init_t *init, const uint8_t *bits); + int is_empty(const uint8_t* d, int l); int count_set_bits(const uint8_t* d, int l); @@ -87,11 +91,17 @@ int frame_get_bit(const uint8_t* frame_d, int bit); void frame_clear_bit(uint8_t* frame_d, int bit); void frame_set_bit(uint8_t* frame_d, int bit); +// cpuword returns the word in such a way that a bit +// index (cpuword & (1<