From d8a18a603423dc8ab017d83a55eb7ce6016ff952 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Mon, 20 Aug 2012 04:42:18 +0200 Subject: [PATCH] bit2fp cleanup --- .gitignore | 1 + Makefile | 10 ++- README | 4 +- bit.h | 31 ++----- bit2fp.c | 35 +++++--- bit_frames.c | 80 +++++++++++++++++- bit_regs.c | 134 ++++++++++++++--------------- floorplan.c | 13 ++- floorplan.h | 4 +- helper.c | 31 +++++-- helper.h | 4 +- not-needed.h | 233 --------------------------------------------------- parts.c | 87 +++++++++++++++++++ parts.h | 26 ++++++ 14 files changed, 334 insertions(+), 359 deletions(-) delete mode 100644 not-needed.h create mode 100644 parts.c create mode 100644 parts.h diff --git a/.gitignore b/.gitignore index 16aeaf3..8a55aa5 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ fp2bit fp2bit.o bit2fp bit2fp.o +parts.o autotest.tmp/ diff --git a/Makefile b/Makefile index 4eeff4f..bf780dd 100644 --- a/Makefile +++ b/Makefile @@ -28,11 +28,13 @@ new_fp: new_fp.o $(MODEL_OBJ) floorplan.o helper.o control.o new_fp.o: new_fp.c floorplan.h model.h helper.h control.h -fp2bit: fp2bit.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o bit_frames.o helper.o +fp2bit: fp2bit.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o bit_frames.o \ + helper.o parts.o fp2bit.o: fp2bit.c model.h floorplan.h bit.h helper.h -bit2fp: bit2fp.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o bit_frames.o helper.o +bit2fp: bit2fp.o $(MODEL_OBJ) floorplan.o control.o bit_regs.o \ + bit_frames.o helper.o parts.o bit2fp.o: bit2fp.c model.h floorplan.h bit.h helper.h @@ -42,6 +44,8 @@ bit_regs.o: bit_regs.c bit.h model.h bit_frames.o: bit_frames.c bit.h model.h +parts.o: parts.c parts.h + control.o: control.c control.h model.h draw_svg_tiles: draw_svg_tiles.o $(MODEL_OBJ) helper.o control.o @@ -129,7 +133,7 @@ clean: autotest autotest.o control.o floorplan.o \ fp2bit fp2bit.o \ bit2fp bit2fp.o \ - bit_regs.o bit_frames.o \ + bit_regs.o bit_frames.o parts.o \ pair2net pair2net.o \ xc6slx9_empty.fp xc6slx9.svg \ xc6slx9_empty.tiles xc6slx9_empty.devs xc6slx9_empty.conns \ diff --git a/README b/README index c2d446e..8481b83 100644 --- a/README +++ b/README @@ -11,7 +11,7 @@ Libraries (most is to-be-done) - libfpga-model memory-only representation of an FPGA -- libfpga-bits reads and writes .bit bitstream files +- libfpga-bit reads and writes .bit bitstream files - libfpga-floorplan reads and writes .fp floorplan files - libfpga-control programmatic access to libfpga-model - libfpga-design larger design elements on top of libfpga-control @@ -27,7 +27,7 @@ Design Utilities fpgatools Development Utilities - autotest executes test suite -- 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 +- hstrrep high-speed hashed array based search and replace util diff --git a/bit.h b/bit.h index 04b49bd..212286a 100644 --- a/bit.h +++ b/bit.h @@ -5,24 +5,6 @@ // For details see the UNLICENSE file at the root of the source tree. // -// The highest 4 bits are the binary revision and not -// used when performing IDCODE verification. -// ug380, Configuration Sequence, page 78 -#define IDCODE_MASK 0x0FFFFFFF - -#define XC6SLX4 0x04000093 -#define XC6SLX9 0x04001093 -#define XC6SLX16 0x04002093 -#define XC6SLX25 0x04004093 -#define XC6SLX25T 0x04024093 -#define XC6SLX45 0x04008093 -#define XC6SLX45T 0x04028093 -#define XC6SLX75 0x0400E093 -#define XC6SLX75T 0x0402E093 -#define XC6SLX100 0x04011093 -#define XC6SLX100T 0x04031093 -#define XC6SLX150 0x0401D093 - // xc6 configuration registers, documentation in ug380, page90 enum fpga_config_reg { CRC = 0, FAR_MAJ, FAR_MIN, FDRI, FDRO, CMD, CTL, MASK, STAT, LOUT, COR1, @@ -92,6 +74,12 @@ enum { #define MAX_HEADER_STR_LEN 128 #define MAX_REG_ACTIONS 256 +struct fpga_bits +{ + uint8_t* d; + int len; +}; + struct fpga_config { char header_str[4][MAX_HEADER_STR_LEN]; @@ -103,8 +91,7 @@ struct fpga_config int idcode_reg; int FLR_reg; - int bits_len; - uint8_t* bits; + struct fpga_bits bits; }; int read_bitfile(struct fpga_config* cfg, FILE* f); @@ -118,5 +105,5 @@ void free_config(struct fpga_config* cfg); int write_bitfile(FILE* f, struct fpga_model* model); -int extract_model(struct fpga_model* model, uint8_t* bits, int bits_len); -int write_model(uint8_t* bits, int bits_len, struct fpga_model* model); +int extract_model(struct fpga_model* model, struct fpga_bits* bits); +int write_model(struct fpga_bits* bits, struct fpga_model* model); diff --git a/bit2fp.c b/bit2fp.c index 30d557e..493afd3 100644 --- a/bit2fp.c +++ b/bit2fp.c @@ -12,7 +12,7 @@ int main(int argc, char** argv) { struct fpga_model model; - int bits_only, file_arg, rc = -1; + int bit_header, bit_regs, fp_header, file_arg, flags, rc = -1; struct fpga_config config; // parameters @@ -20,16 +20,24 @@ int main(int argc, char** argv) fprintf(stderr, "\n" "%s - bitstream to floorplan\n" - "Usage: %s [--bits-only] \n" + "Usage: %s [--bit-header] [--bit-regs] [--no-fp-header] \n" "\n", argv[0], argv[0]); goto fail; } - bits_only = 0; + bit_header = 0; + bit_regs = 0; + fp_header = 1; file_arg = 1; - if (!strcmp(argv[1], "--bits-only")) { - bits_only = 1; - file_arg = 2; - } + while (!strncmp(argv[file_arg], "--", 2)) { + if (!strcmp(argv[file_arg], "--bit-header")) + bit_header = 1; + else if (!strcmp(argv[file_arg], "--bit-regs")) + bit_regs = 1; + else if (!strcmp(argv[file_arg], "--no-fp-header")) + fp_header = 0; + else break; + file_arg++; + } // read bitstream file { @@ -46,15 +54,18 @@ int main(int argc, char** argv) // build model and fill from bitstream if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc); - if ((rc = extract_model(&model, config.bits, config.bits_len))) FAIL(rc); + if ((rc = extract_model(&model, &config.bits))) FAIL(rc); // dump model - if ((rc = write_floorplan(stdout, &model, - bits_only ? FP_BITS_ONLY : FP_BITS_DEFAULT))) FAIL(rc); + flags = FP_DEFAULT; + if (!fp_header) flags |= FP_NO_HEADER; + if ((rc = write_floorplan(stdout, &model, flags))) FAIL(rc); // dump what doesn't fit into the model - if ((rc = dump_config(&config, bits_only ? DUMP_BITS - : DUMP_BITS|DUMP_HEADER_STR|DUMP_REGS))) FAIL(rc); + flags = DUMP_BITS; + if (bit_header) flags |= DUMP_HEADER_STR; + if (bit_regs) flags |= DUMP_REGS; + if ((rc = dump_config(&config, flags))) FAIL(rc); return EXIT_SUCCESS; fail: return rc; diff --git a/bit_frames.c b/bit_frames.c index b667eeb..b3e57c9 100644 --- a/bit_frames.c +++ b/bit_frames.c @@ -7,13 +7,87 @@ #include "model.h" #include "bit.h" +#include "parts.h" -int extract_model(struct fpga_model* model, uint8_t* bits, int bits_len) +static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major) { - return 0; + int i, num_frames; + + num_frames = 0; + for (i = 0; i < major; i++) + num_frames += get_major_minors(XC6SLX9, i); + return &bits->d[(row*FRAMES_PER_ROW + num_frames)*FRAME_SIZE]; } -int write_model(uint8_t* bits, int bits_len, struct fpga_model* model) +static int get_bit(struct fpga_bits* bits, + int row, int major, int minor, int bit_i) { + return get_framebit(get_first_minor(bits, row, major) + + minor*FRAME_SIZE, bit_i); +} + +static void set_bit(struct fpga_bits* bits, + int row, int major, int minor, int bit_i) +{ + return set_framebit(get_first_minor(bits, row, major) + + minor*FRAME_SIZE, bit_i); +} + +static void clear_bit(struct fpga_bits* bits, + int row, int major, int minor, int bit_i) +{ + return clear_framebit(get_first_minor(bits, row, major) + + minor*FRAME_SIZE, bit_i); +} + +struct bit_pos +{ + int row; + int major; + int minor; + int bit_i; +}; + +static int get_bitp(struct fpga_bits* bits, struct bit_pos* pos) +{ + return get_bit(bits, pos->row, pos->major, pos->minor, pos->bit_i); +} + +static void set_bitp(struct fpga_bits* bits, struct bit_pos* pos) +{ + set_bit(bits, pos->row, pos->major, pos->minor, pos->bit_i); +} + +static void clear_bitp(struct fpga_bits* bits, struct bit_pos* pos) +{ + clear_bit(bits, pos->row, pos->major, pos->minor, pos->bit_i); +} + +static struct bit_pos s_default_bits[] = { + { 0, 0, 3, 66 }, + { 0, 1, 23, 1034 }, + { 0, 1, 23, 1035 }, + { 0, 1, 23, 1039 }, + { 2, 0, 3, 66 }}; + +int extract_model(struct fpga_model* model, struct fpga_bits* bits) +{ + int i, rc; + + for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++) { + if (!get_bitp(bits, &s_default_bits[i])) + FAIL(EINVAL); + clear_bitp(bits, &s_default_bits[i]); + } + return 0; +fail: + return rc; +} + +int write_model(struct fpga_bits* bits, struct fpga_model* model) +{ + int i; + for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++) + set_bitp(bits, &s_default_bits[i]); return 0; } diff --git a/bit_regs.c b/bit_regs.c index e2a23a2..c1d34c4 100644 --- a/bit_regs.c +++ b/bit_regs.c @@ -7,34 +7,13 @@ #include "model.h" #include "bit.h" +#include "parts.h" static int parse_header(struct fpga_config* config, uint8_t* d, int len, int inpos, int* outdelta); static int parse_commands(struct fpga_config* config, uint8_t* d, int len, int inpos); -static const int minors_per_major[] = -{ - /* 0 */ 4, // 505 bytes = middle 8-bit for each minor? - /* 1 */ 30, // left - /* 2 */ 31, // logic M - /* 3 */ 30, // logic L - /* 4 */ 25, // bram - /* 5 */ 31, // logic M - /* 6 */ 30, // logic L - /* 7 */ 24, // macc - /* 8 */ 31, // logic M - /* 9 */ 31, // center - /* 10 */ 31, // logic M - /* 11 */ 30, // logic L - /* 12 */ 31, // logic M - /* 13 */ 30, // logic L - /* 14 */ 25, // bram - /* 15 */ 31, // logic M - /* 16 */ 30, // logic L - /* 17 */ 30, // right -}; - #define SYNC_WORD 0xAA995566 #define PACKET_HDR_TYPE_S 13 @@ -818,17 +797,17 @@ static void printf_clb(uint8_t* maj_bits, int row, int major) // bits for (j = 0; j < 64; j++) { - if (bit_set(&maj_bits[20*130], frame_off + j)) + if (get_framebit(&maj_bits[20*130], frame_off + j)) printf("r%i ma%i clb i%i mi20 bit %i\n", row, major, i-start, j); } for (j = 0; j < 64; j++) { - if (bit_set(&maj_bits[23*130], frame_off + j)) + if (get_framebit(&maj_bits[23*130], frame_off + j)) printf("r%i ma%i clb i%i mi23 bit %i\n", row, major, i-start, j); } for (j = 0; j < 64; j++) { - if (bit_set(&maj_bits[26*130], frame_off + j)) + if (get_framebit(&maj_bits[26*130], frame_off + j)) printf("r%i ma%i clb i%i mi26 bit %i\n", row, major, i-start, j); } @@ -852,21 +831,21 @@ static int dump_bits(struct fpga_config* cfg) last_extra_minor = 21; minor = 0; while (minor <= last_extra_minor) { - minor += printf_frames(&cfg->bits[off + minor += printf_frames(&cfg->bits.d[off +minor*130], 31 - minor, row, major, minor, /*print_empty*/ 0); } // clock for (; minor < 24; minor++) - printf_clock(&cfg->bits[off+minor*130], + printf_clock(&cfg->bits.d[off+minor*130], row, major, minor); for (i = 0; i < 4; i++) { for (minor = last_extra_minor+1; minor < 24; minor++) { for (j = 0; j < 256; j++) { - if (bit_set(&cfg->bits[off+minor*130], i*256 + ((i>=2)?16:0) + j)) + if (get_framebit(&cfg->bits.d[off+minor*130], i*256 + ((i>=2)?16:0) + j)) printf("r%i ma%i dsp i%i mi%i bit %i\n", row, major, i, minor, i*256+j); } } @@ -876,46 +855,46 @@ static int dump_bits(struct fpga_config* cfg) || major == 13 || major == 15 || major == 16) { // logic minor = 0; while (minor < 20) { - minor += printf_frames(&cfg->bits[off + minor += printf_frames(&cfg->bits.d[off +minor*130], 31 - minor, row, major, minor, /*print_empty*/ 0); } // clock for (minor = 20; minor < 31; minor++) - printf_clock(&cfg->bits[off+minor*130], + printf_clock(&cfg->bits.d[off+minor*130], row, major, minor); // extra bits at bottom of row0 and top of row3 if (row == 3) - printf_extrabits(&cfg->bits[off], 20, 11, + printf_extrabits(&cfg->bits.d[off], 20, 11, 0, 128, row, major); else if (!row) - printf_extrabits(&cfg->bits[off], 20, 11, + printf_extrabits(&cfg->bits.d[off], 20, 11, 14*64 + 16, 128, row, major); // clbs - printf_clb(&cfg->bits[off], row, major); + printf_clb(&cfg->bits.d[off], row, major); } else if (major == 4 || major == 14) { // bram ramb16_cfg_t ramb16_cfg[4]; // minors 0..22 minor = 0; while (minor < 23) { - minor += printf_frames(&cfg->bits[off + minor += printf_frames(&cfg->bits.d[off +minor*130], 23 - minor, row, major, minor, /*print_empty*/ 0); } // minors 23&24 - printf_clock(&cfg->bits[off+23*130], row, major, 23); - printf_clock(&cfg->bits[off+24*130], row, major, 24); + printf_clock(&cfg->bits.d[off+23*130], row, major, 23); + printf_clock(&cfg->bits.d[off+24*130], row, major, 24); for (i = 0; i < 4; i++) { offset_in_frame = i*32; if (offset_in_frame >= 64) offset_in_frame += 2; for (j = 0; j < 32; j++) { - ramb16_cfg[i].byte[j] = cfg->bits[off+23*130+offset_in_frame+j]; - ramb16_cfg[i].byte[j+32] = cfg->bits[off+24*130+offset_in_frame+j]; + ramb16_cfg[i].byte[j] = cfg->bits.d[off+23*130+offset_in_frame+j]; + ramb16_cfg[i].byte[j+32] = cfg->bits.d[off+24*130+offset_in_frame+j]; } } for (i = 0; i < 4; i++) { @@ -930,14 +909,16 @@ static int dump_bits(struct fpga_config* cfg) print_ramb16_cfg(&ramb16_cfg[i]); } } else { + int major_minors = + get_major_minors(XC6SLX9, major); minor = 0; - while (minor < minors_per_major[major]) { - minor += printf_frames(&cfg->bits[off - +minor*130], minors_per_major[major] - - minor, row, major, minor, /*print_empty*/ 0); + while (minor < major_minors) { + minor += printf_frames(&cfg->bits.d[off + +minor*130], major_minors - minor, + row, major, minor, /*print_empty*/ 0); } } - off += minors_per_major[major] * 130; + off += get_major_minors(XC6SLX9, major) * 130; } } return 0; @@ -951,7 +932,7 @@ static int dump_bram(struct fpga_config* cfg) for (row = 0; row < 4; row++) { for (i = 0; i < 8; i++) { for (j = 0; j < 18*130; j++) { - if (cfg->bits[BRAM_DATA_START + row*144*130 + if (cfg->bits.d[BRAM_DATA_START + row*144*130 + i*18*130 + j]) break; } @@ -964,7 +945,7 @@ static int dump_bram(struct fpga_config* cfg) printf("br%i ramb16 i%i\n", row, i); printf("{\n"); off = BRAM_DATA_START + row*144*130 + i*18*130; - printf_ramb16_data(cfg->bits, off); + printf_ramb16_data(cfg->bits.d, off); printf("}\n"); } } @@ -986,7 +967,7 @@ int dump_config(struct fpga_config* cfg, int flags) if (rc) FAIL(rc); rc = dump_bram(cfg); if (rc) FAIL(rc); - printf_iob(cfg->bits, cfg->bits_len, + printf_iob(cfg->bits.d, cfg->bits.len, BRAM_DATA_START + BRAM_DATA_LEN, 896*2/8); } if (flags & DUMP_REGS) { @@ -1000,8 +981,8 @@ fail: void free_config(struct fpga_config* cfg) { - free(cfg->bits); - cfg->bits = 0; + free(cfg->bits.d); + cfg->bits.d = 0; memset(cfg, 0, sizeof(*cfg)); } @@ -1066,11 +1047,11 @@ static int FAR_pos(int FAR_row, int FAR_major, int FAR_minor) if (FAR_row < 0 || FAR_major < 0 || FAR_minor < 0) return -1; if (FAR_row > 3 || FAR_major > 17 - || FAR_minor >= minors_per_major[FAR_major]) + || FAR_minor >= get_major_minors(XC6SLX9, FAR_major)) return -1; result = FAR_row * 505*130; for (i = 0; i < FAR_major; i++) - result += minors_per_major[i]*130; + result += get_major_minors(XC6SLX9, i)*130; return result + FAR_minor*130; } @@ -1091,9 +1072,9 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in || cfg->reg[cfg->FLR_reg].int_v != 896) FAIL(EINVAL); - cfg->bits_len = (4*505 + 4*144) * 130 + 896*2; - cfg->bits = calloc(cfg->bits_len, 1 /* elsize */); - if (!cfg->bits) FAIL(ENOMEM); + cfg->bits.len = (4*505 + 4*144) * 130 + 896*2; + cfg->bits.d = calloc(cfg->bits.len, 1 /* elsize */); + if (!cfg->bits.d) FAIL(ENOMEM); FAR_block = -1; FAR_row = -1; @@ -1178,7 +1159,7 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in if (FAR_block != 0) FAIL(EINVAL); offset_in_bits = FAR_pos(FAR_row, FAR_major, FAR_minor); if (offset_in_bits == -1) FAIL(EINVAL); - memmove(&cfg->bits[offset_in_bits], &cfg->bits[MFW_src_off], 130); + memmove(&cfg->bits.d[offset_in_bits], &cfg->bits.d[MFW_src_off], 130); src_off += 8; continue; @@ -1241,7 +1222,7 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in padding_frames += 2; continue; } - memcpy(&cfg->bits[offset_in_bits + memcpy(&cfg->bits.d[offset_in_bits + (i-padding_frames)*130], &d[src_off + i*130], 130); } @@ -1250,7 +1231,7 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in int bram_data_words = 4*144*65 + 896; if (u32 - block0_words != bram_data_words + 1) FAIL(EINVAL); offset_in_bits = BRAM_DATA_START; - memcpy(&cfg->bits[offset_in_bits], + memcpy(&cfg->bits.d[offset_in_bits], &d[src_off+block0_words*2], bram_data_words*2); u16 = __be16_to_cpu(*(uint16_t*)&d[ @@ -1264,8 +1245,8 @@ static int read_bits(struct fpga_config* cfg, uint8_t* d, int len, int inpos, in } rc = EINVAL; fail: - free(cfg->bits); - cfg->bits = 0; + free(cfg->bits.d); + cfg->bits.d = 0; return rc; success: *outdelta = src_off - inpos; @@ -1289,7 +1270,7 @@ static int parse_commands(struct fpga_config* cfg, uint8_t* d, if (curpos + cmd_len > len) FAIL(EINVAL); if (curpos + cmd_len < len) { printf("#W Unexpected continuation after offset " - "%i.\n", curpos + 5 + cmd_len); + "%i (len %i).\n", curpos + cmd_len, len); } if (curpos >= len) FAIL(EINVAL); @@ -1678,17 +1659,17 @@ fail: static int write_bits(FILE* f, struct fpga_model* model) { - uint8_t* bits; + struct fpga_bits bits; uint16_t u16; uint32_t u32; - int bits_len, nwritten, i, j, rc; + int nwritten, i, j, rc; char padding_frame[FRAME_SIZE]; - bits_len = IOB_DATA_START + IOB_DATA_LEN; - bits = calloc(bits_len, /*elsize*/ 1); - if (!bits) FAIL(ENOMEM); + bits.len = IOB_DATA_START + IOB_DATA_LEN; + bits.d = calloc(bits.len, /*elsize*/ 1); + if (!bits.d) FAIL(ENOMEM); - rc = write_model(bits, bits_len, model); + rc = write_model(&bits, model); if (rc) FAIL(rc); u16 = PACKET_TYPE_2 << PACKET_HDR_TYPE_S; @@ -1713,7 +1694,7 @@ static int write_bits(FILE* f, struct fpga_model* model) // write rows with padding frames for (i = 0; i < NUM_ROWS; i++) { - nwritten = fwrite(&bits[i*FRAMES_PER_ROW*FRAME_SIZE], + nwritten = fwrite(&bits.d[i*FRAMES_PER_ROW*FRAME_SIZE], /*size*/ 1, FRAMES_PER_ROW*FRAME_SIZE, f); if (nwritten != FRAMES_PER_ROW*FRAME_SIZE) FAIL(errno); for (j = 0; j < PADDING_FRAMES_PER_ROW; j++) { @@ -1724,12 +1705,12 @@ static int write_bits(FILE* f, struct fpga_model* model) } // write bram data - nwritten = fwrite(&bits[BRAM_DATA_START], + nwritten = fwrite(&bits.d[BRAM_DATA_START], /*size*/ 1, BRAM_DATA_LEN, f); if (nwritten != BRAM_DATA_LEN) FAIL(errno); // write IOB data - nwritten = fwrite(&bits[IOB_DATA_START], + nwritten = fwrite(&bits.d[IOB_DATA_START], /*size*/ 1, IOB_DATA_LEN, f); if (nwritten != IOB_DATA_LEN) FAIL(errno); @@ -1743,17 +1724,17 @@ static int write_bits(FILE* f, struct fpga_model* model) nwritten = fwrite(&u32, /*size*/ 1, sizeof(u32), f); if (nwritten != sizeof(u32)) FAIL(errno); - free(bits); + free(bits.d); return 0; fail: - free(bits); + free(bits.d); return rc; } int write_bitfile(FILE* f, struct fpga_model* model) { uint32_t u32; - int len_to_eof_pos, nwritten, i, rc; + int len_to_eof_pos, eof_pos, nwritten, i, rc; rc = write_header(f, "fpgatools.fp;UserID=0xFFFFFFFF", "6slx9tqg144", "2010/05/26", "08:00:00"); @@ -1782,6 +1763,17 @@ int write_bitfile(FILE* f, struct fpga_model* model) rc = write_reg_action(f, &s_defregs_after_bits[i]); if (rc) FAIL(rc); } + + // write len to eof at offset len_to_eof_pos + if ((eof_pos = ftell(f)) == -1) + FAIL(errno); + if (fseek(f, len_to_eof_pos, SEEK_SET) == -1) + FAIL(errno); + u32 = __cpu_to_be32(eof_pos - len_to_eof_pos - sizeof(u32)); + nwritten = fwrite(&u32, /*size*/ 1, sizeof(u32), f); + if (nwritten != sizeof(u32)) FAIL(errno); + if (fseek(f, eof_pos, SEEK_SET) == -1) + FAIL(errno); return 0; fail: return rc; diff --git a/floorplan.c b/floorplan.c index 4f86bd4..7a0ab0c 100644 --- a/floorplan.c +++ b/floorplan.c @@ -760,7 +760,18 @@ next_line: ; int write_floorplan(FILE* f, struct fpga_model* model, int flags) { - if (!(flags & FP_BITS_ONLY)) + int rc; + + if (!(flags & FP_NO_HEADER)) printf_version(f); + + rc = printf_devices(f, model, /*config_only*/ 1); + if (rc) FAIL(rc); + + rc = printf_switches(f, model, /*enabled_only*/ 1); + if (rc) FAIL(rc); + return 0; +fail: + return rc; } diff --git a/floorplan.h b/floorplan.h index 9716f65..581f63a 100644 --- a/floorplan.h +++ b/floorplan.h @@ -25,8 +25,8 @@ // int read_floorplan(struct fpga_model* model, FILE* f); -#define FP_BITS_DEFAULT 0x0000 -#define FP_BITS_ONLY 0x0001 +#define FP_DEFAULT 0x0000 +#define FP_NO_HEADER 0x0001 int write_floorplan(FILE* f, struct fpga_model* model, int flags); void printf_version(FILE* f); diff --git a/helper.c b/helper.c index 0779511..f257a80 100644 --- a/helper.c +++ b/helper.c @@ -480,9 +480,22 @@ int count_bits(uint8_t* d, int l) return bits; } -int bit_set(uint8_t* frame_d, int bit) +int get_framebit(uint8_t* frame_d, int bit) { - return (frame_d[(bit/16)*2 + !((bit/8)%2)] & 1<<(7-(bit%8))) != 0; + uint8_t v = 1<<(7-(bit%8)); + return (frame_d[(bit/16)*2 + !((bit/8)%2)] & v) != 0; +} + +void clear_framebit(uint8_t* frame_d, int bit) +{ + uint8_t v = 1<<(7-(bit%8)); + frame_d[(bit/16)*2 + !((bit/8)%2)] &= ~v; +} + +void set_framebit(uint8_t* frame_d, int bit) +{ + uint8_t v = 1<<(7-(bit%8)); + frame_d[(bit/16)*2 + !((bit/8)%2)] |= v; } int printf_frames(uint8_t* bits, int max_frames, @@ -512,7 +525,7 @@ int printf_frames(uint8_t* bits, int max_frames, if (count_bits(bits, 130) <= 32) { printf_clock(bits, row, major, minor); for (i = 0; i < 1024; i++) { - if (bit_set(bits, (i >= 512) ? i + 16 : i)) + if (get_framebit(bits, (i >= 512) ? i + 16 : i)) printf("%sbit %i\n", prefix, i); } return 1; @@ -528,7 +541,7 @@ void printf_clock(uint8_t* frame, int row, int major, int minor) { int i; for (i = 0; i < 16; i++) { - if (bit_set(frame, 512 + i)) + if (get_framebit(frame, 512 + i)) printf("r%i ma%i mi%i clock %i\n", row, major, minor, i); } @@ -557,7 +570,7 @@ void printf_extrabits(uint8_t* maj_bits, int start_minor, int num_minors, for (minor = start_minor; minor < start_minor + num_minors; minor++) { for (bit = start_bit; bit < start_bit + num_bits; bit++) { - if (bit_set(&maj_bits[minor*130], bit)) + if (get_framebit(&maj_bits[minor*130], bit)) printf("r%i ma%i extra mi%i bit %i\n", row, major, minor, bit); } @@ -570,13 +583,13 @@ uint64_t read_lut64(uint8_t* two_minors, int off_in_frame) int j; for (j = 0; j < 16; j++) { - if (bit_set(two_minors, off_in_frame+j*2)) + if (get_framebit(two_minors, off_in_frame+j*2)) lut64 |= 1LL << (j*4); - if (bit_set(two_minors, off_in_frame+(j*2)+1)) + if (get_framebit(two_minors, off_in_frame+(j*2)+1)) lut64 |= 1LL << (j*4+1); - if (bit_set(&two_minors[130], off_in_frame+j*2)) + if (get_framebit(&two_minors[130], off_in_frame+j*2)) lut64 |= 1LL << (j*4+2); - if (bit_set(&two_minors[130], off_in_frame+(j*2)+1)) + if (get_framebit(&two_minors[130], off_in_frame+(j*2)+1)) lut64 |= 1LL << (j*4+3); } return lut64; diff --git a/helper.h b/helper.h index 3a46686..c565149 100644 --- a/helper.h +++ b/helper.h @@ -64,7 +64,9 @@ void printf_ramb16_data(uint8_t* bits, int inpos); int is_empty(uint8_t* d, int l); int count_bits(uint8_t* d, int l); -int bit_set(uint8_t* frame_d, int bit); +int get_framebit(uint8_t* frame_d, int bit); +void clear_framebit(uint8_t* frame_d, int bit); +void set_framebit(uint8_t* frame_d, int bit); // if row is negative, it's an absolute frame number and major and // minor are ignored diff --git a/not-needed.h b/not-needed.h deleted file mode 100644 index a4cc5c3..0000000 --- a/not-needed.h +++ /dev/null @@ -1,233 +0,0 @@ -// -// 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. -// - -static const char* iob_xc6slx4_sitenames[896*2/8] = -{ - [0x0000/8] "P70", - "P69", - "P67", - "P66", - "P65", - "P64", - "P62", - "P61", - "P60", - "P59", - "P58", - "P57", - 0, - 0, - 0, - 0, - [0x0080/8] 0, - 0, - "P56", - "P55", - 0, - 0, - 0, - 0, - 0, - 0, - "P51", - "P50", - 0, - 0, - 0, - 0, - [0x0100/8] 0, - 0, - 0, - 0, - "UNB131", - "UNB132", - "P48", - "P47", - "P46", - "P45", - "P44", - "P43", - 0, - 0, - "P41", - "P40", - [0x0180/8] "P39", - "P38", - "P35", - "P34", - "P33", - "P32", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - [0x0200/8] "P30", - "P29", - "P27", - "P26", - 0, - 0, - 0, - 0, - 0, - 0, - "P24", - "P23", - "P22", - "P21", - 0, - 0, - [0x0280/8] 0, - 0, - 0, - 0, - "P17", - "P16", - "P15", - "P14", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - [0x0300/8] "P12", - "P11", - "P10", - "P9", - "P8", - "P7", - "P6", - "P5", - 0, - 0, - 0, - 0, - 0, - 0, - "P2", - "P1", - [0x0380/8] "P144", - "P143", - "P142", - "P141", - "P140", - "P139", - "P138", - "P137", - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - [0x0400/8] 0, - 0, - 0, - 0, - "P134", - "P133", - "P132", - "P131", - 0, - 0, - 0, - 0, - 0, - 0, - "P127", - "P126", - [0x0480/8] "P124", - "P123", - 0, - 0, - 0, - 0, - 0, - 0, - "P121", - "P120", - "P119", - "P118", - "P117", - "P116", - "P115", - "P114", - [0x0500/8] "P112", - "P111", - "P105", - "P104", - 0, - 0, - 0, - 0, - 0, - 0, - "P102", - "P101", - "P99", - "P98", - "P97", - [0x0580/8] 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "P95", - "P94", - "P93", - "P92", - 0, - 0, - [0x0600/8] 0, - 0, - 0, - "P88", - "P87", - 0, - "P85", - "P84", - 0, - 0, - "P83", - "P82", - "P81", - "P80", - "P79", - "P78", - [0x0680/8] 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - "P75", - "P74" -}; diff --git a/parts.c b/parts.c new file mode 100644 index 0000000..2f80935 --- /dev/null +++ b/parts.c @@ -0,0 +1,87 @@ +// +// 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 "helper.h" +#include "parts.h" + +const char* iob_xc6slx4_sitenames[896*2/8] = +{ + [0x0000/8] + "P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61", + "P60", "P59", "P58", "P57", 0, 0, 0, 0, + [0x0080/8] + 0, 0, "P56", "P55", 0, 0, 0, 0, + 0, 0, "P51", "P50", 0, 0, 0, 0, + [0x0100/8] + 0, 0, 0, 0, "UNB131", "UNB132", "P48", "P47", + "P46", "P45", "P44", "P43", 0, 0, "P41", "P40", + [0x0180/8] + "P39", "P38", "P35", "P34", "P33", "P32", 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + [0x0200/8] + "P30", "P29", "P27", "P26", 0, 0, 0, 0, + 0, 0, "P24", "P23", "P22", "P21", 0, 0, + [0x0280/8] + 0, 0, 0, 0, "P17", "P16", "P15", "P14", + 0, 0, 0, 0, 0, 0, 0, 0, + [0x0300/8] + "P12", "P11", "P10", "P9", "P8", "P7", "P6", "P5", + 0, 0, 0, 0, 0, 0, "P2", "P1", + [0x0380/8] + "P144", "P143", "P142", "P141", "P140", "P139", "P138", "P137", + 0, 0, 0, 0, 0, 0, 0, 0, + [0x0400/8] + 0, 0, 0, 0, "P134", "P133", "P132", "P131", + 0, 0, 0, 0, 0, 0, "P127", "P126", + [0x0480/8] + "P124", "P123", 0, 0, 0, 0, 0, 0, + "P121", "P120", "P119", "P118", "P117", "P116", "P115", "P114", + [0x0500/8] + "P112", "P111", "P105", "P104", 0, 0, 0, 0, + 0, 0, "P102", "P101", "P99", "P98", "P97", 0, + [0x0580/8] + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, "P95", "P94", "P93", "P92", 0, 0, + [0x0600/8] + 0, 0, 0, "P88", "P87", 0, "P85", "P84", + 0, 0, "P83", "P82", "P81", "P80", "P79", "P78", + [0x0680/8] + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, "P75", "P74" +}; + +static const int minors_per_major[] = // for slx4 and slx9 +{ + /* 0 */ 4, // 505 bytes = middle 8-bit for each minor? + /* 1 */ 30, // left + /* 2 */ 31, // logic M + /* 3 */ 30, // logic L + /* 4 */ 25, // bram + /* 5 */ 31, // logic M + /* 6 */ 30, // logic L + /* 7 */ 24, // macc + /* 8 */ 31, // logic M + /* 9 */ 31, // center + /* 10 */ 31, // logic M + /* 11 */ 30, // logic L + /* 12 */ 31, // logic M + /* 13 */ 30, // logic L + /* 14 */ 25, // bram + /* 15 */ 31, // logic M + /* 16 */ 30, // logic L + /* 17 */ 30, // right +}; + +int get_major_minors(int idcode, int major) +{ + if ((idcode & IDCODE_MASK) != XC6SLX9) + EXIT(1); + if (major < 0 || major + > sizeof(minors_per_major)/sizeof(minors_per_major[0])) + EXIT(1); + return minors_per_major[major]; +} diff --git a/parts.h b/parts.h new file mode 100644 index 0000000..6cd20b7 --- /dev/null +++ b/parts.h @@ -0,0 +1,26 @@ +// +// 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. +// + +// The highest 4 bits are the binary revision and not +// used when performing IDCODE verification. +// ug380, Configuration Sequence, page 78 +#define IDCODE_MASK 0x0FFFFFFF + +#define XC6SLX4 0x04000093 +#define XC6SLX9 0x04001093 +#define XC6SLX16 0x04002093 +#define XC6SLX25 0x04004093 +#define XC6SLX25T 0x04024093 +#define XC6SLX45 0x04008093 +#define XC6SLX45T 0x04028093 +#define XC6SLX75 0x0400E093 +#define XC6SLX75T 0x0402E093 +#define XC6SLX100 0x04011093 +#define XC6SLX100T 0x04031093 +#define XC6SLX150 0x0401D093 + +int get_major_minors(int idcode, int major);