initial lut support

This commit is contained in:
Wolfgang Spraul 2012-06-29 08:07:38 +02:00
parent 09be589957
commit 9539c70fb6
3 changed files with 193 additions and 55 deletions

167
bit2txt.c
View File

@ -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;
for (row = 0; row < 4; row++) {
printf("\n");
for (row = 0; row < 4; row++) {
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,26 +647,11 @@ 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);
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;
while (minor < majors[major].minors) {
@ -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

View File

@ -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<<j))
if (j != 2 && (i & (1<<j)))
vars[j] = !vars[j];
}
if (((i&8) != 0) ^ ((i&4) != 0))
vars[2] = 1;
result = bool_eval(expr, strlen(expr), vars);
if (result == -1) return -1;
if (result) *lut |= 1LL<<i;
@ -280,7 +283,7 @@ typedef struct _minterm_entry
} minterm_entry;
// 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)
{
// round 0 needs 64 entries
// round 1 (size2): 192
@ -293,6 +296,7 @@ void lut2bool(const uint64_t lut, int bits, char* str)
int mt_size[7];
int i, j, k, round, only_diff_bit;
int str_end, first_op;
static char str[2048];
memset(mt, 0, sizeof(mt));
memset(mt_size, 0, sizeof(mt_size));
@ -306,10 +310,12 @@ void lut2bool(const uint64_t lut, int bits, char* str)
mt[0][mt_size[0]].a[4] = lut_base_vars[4];
mt[0][mt_size[0]].a[5] = lut_base_vars[5];
for (j = 0; j < 6; j++) {
if (i & (1<<j))
if (j != 2 && (i&(1<<j)))
mt[0][mt_size[0]].a[j]
= !mt[0][mt_size[0]].a[j];
}
if (((i&8) != 0) ^ ((i&4) != 0))
mt[0][mt_size[0]].a[2] = 1;
mt_size[0]++;
}
}
@ -317,7 +323,7 @@ void lut2bool(const uint64_t lut, int bits, char* str)
// special case: no minterms -> 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;
}

View File

@ -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);