From 9539c70fb6cf6dfc4b07b99c5312a8e52e5a090b Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Fri, 29 Jun 2012 08:07:38 +0200 Subject: [PATCH] initial lut support --- bit2txt.c | 169 +++++++++++++++++++++++++++++++++++++++--------------- helper.c | 71 ++++++++++++++++++++--- helper.h | 8 ++- 3 files changed, 193 insertions(+), 55 deletions(-) diff --git a/bit2txt.c b/bit2txt.c index a9e7756..eccfb72 100644 --- a/bit2txt.c +++ b/bit2txt.c @@ -484,7 +484,8 @@ int full_map(uint8_t* bit_file, int bf_len, int first_FAR_off, memcpy(&(*bits)[offset_in_bits], &bit_file[src_off+block0_words*2], bram_data_words*2); - u16 = __be16_to_cpu(*(uint16_t*)&bit_file[(src_off+block0_words+bram_data_words)*2]); + u16 = __be16_to_cpu(*(uint16_t*)&bit_file[ + (src_off+block0_words+bram_data_words)*2]); if (u16) goto fail; } src_off += 2*u32; @@ -501,17 +502,124 @@ success: return 0; } +void printf_clb(uint8_t* maj_bits, int row, int major) +{ + int i, j, start, max_idx, frame_off; + const char* lut_str; + uint64_t lut64; + + // the first two slots on top and bottom row are not used for clb + if (!row) { + start = 2; + max_idx = 16; + } else if (row == 2) { + start = 0; + max_idx = 14; + } else { + start = 0; + max_idx = 16; + } + + for (i = start; i < max_idx; i++) { + if (clb_empty(maj_bits, i)) + continue; + frame_off = i*64; + if (i >= 8) + frame_off += 16; // skip clock bits for idx >= 8 + printf("r%i ma%i clb i%i\n", row, major, i-start); + printf("{\n"); + + // LUTs + lut64 = read_lut64(&maj_bits[24*130], frame_off+32); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s0_A6LUT \"%s\"\n", lut_str); + + lut64 = read_lut64(&maj_bits[21*130], frame_off+32); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s0_B6LUT \"%s\"\n", lut_str); + + lut64 = read_lut64(&maj_bits[24*130], frame_off); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s0_C6LUT \"%s\"\n", lut_str); + + lut64 = read_lut64(&maj_bits[21*130], frame_off); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s0_D6LUT \"%s\"\n", lut_str); + + lut64 = read_lut64(&maj_bits[27*130], frame_off+32); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s1_A6LUT \"%s\"\n", lut_str); + + lut64 = read_lut64(&maj_bits[29*130], frame_off+32); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s1_B6LUT \"%s\"\n", lut_str); + + lut64 = read_lut64(&maj_bits[27*130], frame_off); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s1_C6LUT \"%s\"\n", lut_str); + + lut64 = read_lut64(&maj_bits[29*130], frame_off); + lut_str = lut2bool(lut64, 64); + if (*lut_str) + printf(" s1_D6LUT \"%s\"\n", lut_str); + + // bits + for (j = 0; j < 64; j++) { + if (bit_set(&maj_bits[20*130], frame_off + j)) + printf(" mi20 b%i\n", j); + } + for (j = 0; j < 64; j++) { + if (bit_set(&maj_bits[23*130], frame_off + j)) + printf(" mi23 b%i\n", j); + } + for (j = 0; j < 64; j++) { + if (bit_set(&maj_bits[26*130], frame_off + j)) + printf(" mi26 b%i\n", j); + } + printf("}\n"); + } +} + void printf_bits(uint8_t* bits, int bits_len, int idcode) { - int row, major, minor, nodata_times, i, j, off, bram_data_start; - int offset_in_frame, times; + int row, major, minor, i, j, off, bram_data_start; + int offset_in_frame, newline; // type0 off = 0; + printf("\n"); for (row = 0; row < 4; row++) { - printf("\n"); for (major = 0; major < 18; major++) { - if (majors[major].type == MAJ_BRAM) { + if (majors[major].type == MAJ_CLB) { + minor = 0; + while (minor < 20) { + minor += printf_frames(&bits[off + +minor*130], 31 - minor, row, + major, minor, g_cmd_info); + } + + // clock + for (minor = 20; minor < 31; minor++) + printf_clock(&bits[off+minor*130], + row, major, minor); + // extra bits at bottom of row0 and top of row2 + if (row == 2) + printf_singlebits(&bits[off], 20, 11, + 0, 128, row, major); + else if (!row) + printf_singlebits(&bits[off], 20, 11, + 14*64 + 16, 128, row, major); + + // clbs + printf_clb(&bits[off], row, major); + } else if (majors[major].type == MAJ_BRAM) { ramb16_cfg_t ramb16_cfg[4]; // minors 0..22 @@ -526,7 +634,7 @@ void printf_bits(uint8_t* bits, int bits_len, int idcode) printf_clock(&bits[off+23*130], row, major, 23); printf_clock(&bits[off+24*130], row, major, 24); for (i = 0; i < 4; i++) { - offset_in_frame = (3-i)*32; + offset_in_frame = i*32; if (offset_in_frame >= 64) offset_in_frame += 2; for (j = 0; j < 32; j++) { @@ -539,25 +647,10 @@ void printf_bits(uint8_t* bits, int bits_len, int idcode) if (ramb16_cfg[i].byte[j]) break; } - if (j >= 64) { - times = 1; - while (i+times < 4) { - for (j = 0; j < 64; j++) { - if (ramb16_cfg[i+times].byte[j]) - break; - } - if (j >= 64) times++; - } - if (times > 1) { - printf("r%i m%i ramb16 - *%i\n", row, major, times); - i += times-1; - } else - printf("r%i m%i ramb16 -\n", row, major); - } - else { - printf("r%i m%i ramb16 inst\n", row, major); - print_ramb16_cfg(&ramb16_cfg[i]); - } + if (j >= 64) + continue; + printf("r%i m%i i%i ramb16\n", row, major, i); + print_ramb16_cfg(&ramb16_cfg[i]); } } else { minor = 0; @@ -572,41 +665,27 @@ void printf_bits(uint8_t* bits, int bits_len, int idcode) } // bram - printf("\n"); bram_data_start = 4*505*130; + newline = 0; for (row = 0; row < 4; row++) { - nodata_times = 0; for (i = 0; i < 8; i++) { for (j = 0; j < 18*130; j++) { if (bits[bram_data_start + row*144*130 + i*18*130 + j]) break; } - if (j >= 18*130) { - nodata_times++; + if (j >= 18*130) continue; + if (!newline) { + newline = 1; + printf("\n"); } - if (nodata_times) { - if (nodata_times > 1) - printf("br%i ramb16 - *%i\n", - row, nodata_times); - else - printf("br%i ramb16 -\n", row); - nodata_times = 0; - } - printf("br%i ramb16 data\n", row); + printf("br%i i%i ramb16 data\n", row, i); printf("{\n"); off = bram_data_start + row*144*130 + i*18*130; printf_ramb16_data(bits, off); printf("}\n"); } - if (nodata_times) { - if (nodata_times > 1) - printf("br%i ramb16 - *%i\n", - row, nodata_times); - else - printf("br%i ramb16 -\n", row); - } } // iob diff --git a/helper.c b/helper.c index 83b22dc..f678ef1 100644 --- a/helper.c +++ b/helper.c @@ -147,7 +147,8 @@ int printf_header(uint8_t* d, int len, int inpos, int* outdelta) } // for an equivalent schematic, see lut.svg -const int lut_base_vars[6] = {0 /* A1 */, 1, 0, 0, 0, 1 /* A6 */}; +const int lut_base_vars[6] = {0 /* A1 */, 1, 0 /* A3 - not used */, + 0, 0, 1 /* A6 */}; int bool_nextlen(const char* expr, int len) { @@ -240,9 +241,11 @@ int parse_boolexpr(const char* expr, uint64_t* lut) for (i = 0; i < 64; i++) { memcpy(vars, lut_base_vars, sizeof(vars)); for (j = 0; j < 6; j++) { - if (i & (1< empty string if (mt_size[0] == 0) { str[0] = 0; - return; + return str; } // go through five rounds of merging @@ -374,7 +380,7 @@ void lut2bool(const uint64_t lut, int bits, char* str) && mt[6][i].a[4] == 2 && mt[6][i].a[5] == 2) { strcpy(str, "A6+~A6"); - return; + return str; } } @@ -402,6 +408,7 @@ void lut2bool(const uint64_t lut, int bits, char* str) str[str_end] = 0; // TODO: This could be further simplified, see Petrick's method. // XOR don't simplify well, try A2@A3 + return str; } static const char* iob_xc6slx4_sitenames[896*2/8] = @@ -761,9 +768,9 @@ int count_bits(uint8_t* d, int l) return bits; } -int bit_set(uint8_t* d, int bit) +int bit_set(uint8_t* frame_d, int bit) { - return (d[(bit/16)*2 + !((bit/8)%2)] & 1<<(7-(bit%8))) != 0; + return (frame_d[(bit/16)*2 + !((bit/8)%2)] & 1<<(7-(bit%8))) != 0; } int printf_frames(uint8_t* bits, int max_frames, @@ -813,3 +820,51 @@ void printf_clock(uint8_t* frame, int row, int major, int minor) printf("r%i m%i-%i clock %i\n", row, major, minor, i); } } + +int clb_empty(uint8_t* maj_bits, int idx) +{ + int byte_off, i, minor; + + byte_off = idx * 8; + if (idx >= 8) byte_off += 2; + + for (i = 0; i < 16; i++) { + for (minor = 20; minor < 31; minor++) { + if (!is_empty(&maj_bits[minor*130 + byte_off], 8)) + return 0; + } + } + return 1; +} + +void printf_singlebits(uint8_t* maj_bits, int start_minor, int num_minors, + int start_bit, int num_bits, int row, int major) +{ + int minor, bit; + + 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)) + printf("r%i m%i-%i b%i\n", + row, major, minor, bit); + } + } +} + +uint64_t read_lut64(uint8_t* two_minors, int off_in_frame) +{ + uint64_t lut64 = 0; + int j; + + for (j = 0; j < 16; j++) { + if (bit_set(two_minors, off_in_frame+j*2)) + lut64 |= 1LL << (j*4); + if (bit_set(two_minors, off_in_frame+(j*2)+1)) + lut64 |= 1LL << (j*4+1); + if (bit_set(&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)) + lut64 |= 1LL << (j*4+3); + } + return lut64; +} diff --git a/helper.h b/helper.h index 22a423e..46a08ae 100644 --- a/helper.h +++ b/helper.h @@ -48,17 +48,21 @@ int printf_header(uint8_t* d, int len, int inpos, int* outdelta); void printf_lut6(const char* cfg); // bits is tested only for 32 and 64 -void lut2bool(const uint64_t lut, int bits, char* str); +const char* lut2bool(const uint64_t lut, int bits); int printf_iob(uint8_t* d, int len, int inpos, int num_entries); 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* d, int bit); +int bit_set(uint8_t* frame_d, int bit); // if row is negative, it's an absolute frame number and major and // minor are ignored int printf_frames(uint8_t* bits, int max_frames, int row, int major, int minor, int print_empty); void printf_clock(uint8_t* frame, int row, int major, int minor); +int clb_empty(uint8_t* maj_bits, int idx); +void printf_singlebits(uint8_t* maj_bits, int start_minor, int num_minors, + int start_bit, int num_bits, int row, int major); +uint64_t read_lut64(uint8_t* two_minors, int off_in_frame);