initial lut support
This commit is contained in:
parent
09be589957
commit
9539c70fb6
167
bit2txt.c
167
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;
|
||||
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
|
||||
|
|
71
helper.c
71
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<<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;
|
||||
}
|
||||
|
|
8
helper.h
8
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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user