lut cleanup and support for more cases - unfinished

This commit is contained in:
Wolfgang Spraul 2012-10-05 16:17:08 +02:00
parent 0a0dfaca31
commit 6200ea710c
9 changed files with 426 additions and 94 deletions

46
LINKS
View File

@ -13,8 +13,54 @@ Andrew's redtin logic analyzer
gtkwave wave viewer gtkwave wave viewer
http://gtkwave.sourceforge.net http://gtkwave.sourceforge.net
cores
https://github.com/openrisc/mor1kx
https://github.com/milkymist
Fedora Electronic Lab tool overview Fedora Electronic Lab tool overview
http://spins.fedoraproject.org/fel/#portfolio http://spins.fedoraproject.org/fel/#portfolio
http://chitlesh.fedorapeople.org/FEL/list.html http://chitlesh.fedorapeople.org/FEL/list.html
with links to magic, toped, qucs, iverilog, alliance, etc. with links to magic, toped, qucs, iverilog, alliance, etc.
chip makers
www.xilinx.com FPGA
www.altera.com FPGA
Murata
Peregrine
TriQuint
Maxim
Avago
Skyworks
Analog Devices
standards
IEEE 1149.1 Boundary Scan/JTAG
IEEE 1532 Configuration and Programming
http://www.xilinx.com/products/design_resources/config_sol/isp_standards_specs.htm
materials
www.injectorall.com photoresist
www.dudadiesel.com NaOH, KOH
www.mtixtl.com individual 6'' wafers
www.unitednuclear.com
www.tedpella.com/gold_html/Nanotubes.htm
Carbon Nanotubes
www.tubedevices.com/alek/pwl/pwl_e.htm
Private Tube Manufacture-PWL vacuum tubes
wafer makers
www.oci.co.kr/eng/ OCI (South Korea)
www.gcl-poly.com GCL-Poly (China)
www.hscpoly.com Hemlock (USA)
www.wacker.com/cms/de/wacker_group/divisions/polysilicon/polysilicon.jsp
Wacker (EU)
semiconductor supplies
www.asml.com lithography systems
www.kns.com assembly equipment
foundries
http://cmp.imag.fr/products/ic/?p=prices CMP
www.lfoundry.com analog and mixed signal

View File

@ -82,7 +82,7 @@ libs/%.so: FAKE
test_dirs := $(shell mkdir -p test.gold test.out) test_dirs := $(shell mkdir -p test.gold test.out)
DESIGN_TESTS := hello_world blinking_led DESIGN_TESTS := hello_world blinking_led
AUTO_TESTS := logic_cfg routing_sw io_sw iob_cfg AUTO_TESTS := logic_cfg routing_sw io_sw iob_cfg lut_encoding
COMPARE_TESTS := xc6slx9_tiles xc6slx9_devs xc6slx9_ports xc6slx9_conns xc6slx9_sw xc6slx9_swbits COMPARE_TESTS := xc6slx9_tiles xc6slx9_devs xc6slx9_ports xc6slx9_conns xc6slx9_sw xc6slx9_swbits
DESIGN_GOLD := $(foreach target, $(DESIGN_TESTS), test.gold/design_$(target).fp) DESIGN_GOLD := $(foreach target, $(DESIGN_TESTS), test.gold/design_$(target).fp)

View File

@ -1093,12 +1093,12 @@ fail:
static int test_lut_encoding(struct test_state* tstate) static int test_lut_encoding(struct test_state* tstate)
{ {
int idx_enum[] = { DEV_LOG_M_OR_L, DEV_LOG_X }; int idx_enum[] = { DEV_LOG_M_OR_L, DEV_LOG_X };
int x_enum[] = { /*xm*/ 13, /* center-xl*/ 22, /*xl*/ 39 }; // The center column (x==22 on a xc6slx9) is a regular XL column
int y, x_i, i, j, k, lut_str_len, rc; // for the lut encoding, so it doesn't need separate testing.
int x_enum[] = { /*xm*/ 13, /*xl*/ 39 };
int y, x_i, i, j, lut_str_len, rc;
int type_i, lut; int type_i, lut;
char lut_str[128]; char lut_str[128];
const char* lut5_parents[] = {"(A6+~A6)*1", "(A6+~A6)*0",
"(A6+~A6)*A1", "(A6+~A6)*A3", 0};
tstate->diff_to_null = 1; tstate->diff_to_null = 1;
@ -1135,36 +1135,35 @@ static int test_lut_encoding(struct test_state* tstate)
if (rc) FAIL(rc); if (rc) FAIL(rc);
} }
// lut6 and lut5 pairs // lut6 and lut5 pairs
i = 0; rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
while (lut5_parents[i]) { lut, /*lut6*/ "(A6+~A6)*1", /*lut5*/ "0");
if (rc) FAIL(rc);
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ "(A6+~A6)*0", /*lut5*/ "1");
if (rc) FAIL(rc);
for (i = '1'; i <= '5'; i++) {
snprintf(lut_str, sizeof(lut_str), "A%c", i);
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i], rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ "0"); lut,
/*lut6*/ pf("(A6+~A6)*%s", lut_str),
/*lut5*/ lut_str);
if (rc) FAIL(rc); if (rc) FAIL(rc);
}
for (i = 0; i < 32; i++) {
lut_str_len = 0;
for (j = 0; j < 5; j++) {
if (lut_str_len)
lut_str[lut_str_len++] = '*';
if (!(i & (1<<j)))
lut_str[lut_str_len++] = '~';
lut_str[lut_str_len++] = 'A';
lut_str[lut_str_len++] = '1' + j;
}
lut_str[lut_str_len] = 0;
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i], rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ "1"); lut, /*lut6*/ pf("(A6+~A6)*%s", lut_str),
/*lut5*/ lut_str);
if (rc) FAIL(rc); if (rc) FAIL(rc);
for (j = '1'; j <= '5'; j++) {
snprintf(lut_str, sizeof(lut_str), "A%c", j);
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ lut_str);
if (rc) FAIL(rc);
}
for (j = 0; j < 32; j++) {
lut_str_len = 0;
for (k = 0; k < 5; k++) {
if (lut_str_len)
lut_str[lut_str_len++] = '*';
if (!(j & (1<<k)))
lut_str[lut_str_len++] = '~';
lut_str[lut_str_len++] = 'A';
lut_str[lut_str_len++] = '1' + k;
}
lut_str[lut_str_len] = 0;
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_i],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ lut_str);
if (rc) FAIL(rc);
}
i++;
} }
} }
} }
@ -1211,6 +1210,39 @@ int main(int argc, char** argv)
// for example: ./autotest 2>&1 | tee autotest.log // for example: ./autotest 2>&1 | tee autotest.log
setvbuf(stdout, /*buf*/ 0, _IOLBF, /*size*/ 0); setvbuf(stdout, /*buf*/ 0, _IOLBF, /*size*/ 0);
#if 0
int lut_map1[64] = {63,62,61,60,59,58,57,56,55,54,53,52,51,50,
49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,
30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,
9,8,7,6,5,4,3,2,1,0};
//int bool_str2bits(const char* str, uint64_t* u64, int num_bits);
//const char* bool_bits2str(uint64_t u64, int num_bits);
{
uint64_t u64, u64_2;
rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*~A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("A6*A5*A4*A3*A2*A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("A5*A4*A3*A2*A1", &u64, 32);
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
rc = bool_str2bits("A4*A3", &u64, 32);
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
rc = bool_str2bits("A1", &u64, 64);
printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64));
rc = bool_str2bits("A1", &u64, 32);
printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32));
u64 = 1;
u64_2 = map_bits(u64, 64, lut_map1);
printf("u %llX mapped %llX\n", u64, u64_2);
return 0;
}
#endif
if (argc < 2) { if (argc < 2) {
printf_help(argv[0], available_tests); printf_help(argv[0], available_tests);
return 0; return 0;

View File

@ -764,32 +764,31 @@ static void printf_v64_mi20(const uint8_t* bits, int row, int major)
static void printf_lut(const uint8_t* bits, int row, int major, static void printf_lut(const uint8_t* bits, int row, int major,
int minor, int v32_i) int minor, int v32_i)
{ {
int i, byte_off_in_frame;
uint32_t u32;
uint64_t u64;
char bit_str[64]; char bit_str[64];
uint64_t u64;
int i, num_on_bits;
byte_off_in_frame = v32_i*4; u64 = frame_get_lut64(&bits[minor*FRAME_SIZE], v32_i);
if (byte_off_in_frame >= 64)
byte_off_in_frame += XC6_HCLK_BYTES;
u64 = read_lut64(&bits[minor*FRAME_SIZE], byte_off_in_frame*8);
if (u64) { if (u64) {
for (i = 0; i < 64; i++) num_on_bits = 0;
bit_str[i] = (u64 & (1ULL << i)) ? '1' : '0'; for (i = 0; i < 64; i++) {
printf("r%i ma%i v32_%02i mip%i_lut %.64s\n", row, if (u64 & (1ULL << i))
major, v32_i, minor, bit_str); num_on_bits++;
}
u32 = frame_get_u32(&bits[minor*FRAME_SIZE + byte_off_in_frame]); if (num_on_bits < 5) {
for (i = 0; i < 32; i++) printf("r%i ma%02i v32_%02i mip%02i_lut", row,
bit_str[i] = (u32 & (1 << i)) ? '1' : '0'; major, v32_i, minor);
printf("r%i ma%i v32_%02i mi%i_f32 %.32s\n", row, major, for (i = 0; i < 64; i++) {
v32_i, minor, bit_str); if (u64 & (1ULL << i))
printf(" b%i", i);
u32 = frame_get_u32(&bits[(minor+1)*FRAME_SIZE + byte_off_in_frame]); }
for (i = 0; i < 32; i++) printf("\n");
bit_str[i] = (u32 & (1 << i)) ? '1' : '0'; } else {
printf("r%i ma%i v32_%02i mi%i_f32 %.32s\n", row, major, for (i = 0; i < 64; i++)
v32_i, minor+1, bit_str); bit_str[i] = (u64 & (1ULL << i)) ? '1' : '0';
printf("r%i ma%02i v32_%02i mip%02i_lut %.64s\n", row,
major, v32_i, minor, bit_str);
}
} }
} }
@ -833,6 +832,8 @@ static int dump_maj_center(const uint8_t* bits, int row, int major)
{ {
int minor, i; int minor, i;
if (get_major_minors(XC6SLX9, major) != 31) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++) for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor); printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
@ -850,10 +851,17 @@ static int dump_maj_center(const uint8_t* bits, int row, int major)
printf_lut(bits, row, major, 21, i*2+1); printf_lut(bits, row, major, 21, i*2+1);
printf_lut(bits, row, major, 23, i*2+1); printf_lut(bits, row, major, 23, i*2+1);
} }
printf_frames(&bits[25*FRAME_SIZE], /*max_frames*/ 1,
for (minor = 25; minor < get_major_minors(XC6SLX9, major); minor++) row, major, 25, /*print_empty*/ 0, /*no_clock*/ 1);
printf_frames(&bits[minor*FRAME_SIZE], /*max_frames*/ 1, // X devices
row, major, minor, /*print_empty*/ 0, /*no_clock*/ 1); for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 26, i*2);
printf_lut(bits, row, major, 28, i*2);
printf_lut(bits, row, major, 26, i*2+1);
printf_lut(bits, row, major, 28, i*2+1);
}
printf_frames(&bits[30*FRAME_SIZE], /*max_frames*/ 1,
row, major, 30, /*print_empty*/ 0, /*no_clock*/ 1);
return 0; return 0;
} }
@ -861,6 +869,8 @@ static int dump_maj_logic_xm(const uint8_t* bits, int row, int major)
{ {
int minor, i; int minor, i;
if (get_major_minors(XC6SLX9, major) != 31) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++) for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor); printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
@ -902,6 +912,8 @@ static int dump_maj_logic_xl(const uint8_t* bits, int row, int major)
{ {
int minor, i; int minor, i;
if (get_major_minors(XC6SLX9, major) != 30) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++) for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor); printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
@ -919,10 +931,15 @@ static int dump_maj_logic_xl(const uint8_t* bits, int row, int major)
printf_lut(bits, row, major, 21, i*2+1); printf_lut(bits, row, major, 21, i*2+1);
printf_lut(bits, row, major, 23, i*2+1); printf_lut(bits, row, major, 23, i*2+1);
} }
printf_frames(&bits[25*FRAME_SIZE], /*max_frames*/ 1,
for (minor = 25; minor < get_major_minors(XC6SLX9, major); minor++) row, major, 25, /*print_empty*/ 0, /*no_clock*/ 1);
printf_frames(&bits[minor*FRAME_SIZE], /*max_frames*/ 1, // X devices
row, major, minor, /*print_empty*/ 0, /*no_clock*/ 1); for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 26, i*2);
printf_lut(bits, row, major, 28, i*2);
printf_lut(bits, row, major, 26, i*2+1);
printf_lut(bits, row, major, 28, i*2+1);
}
return 0; return 0;
} }

View File

@ -478,7 +478,6 @@ int fdev_logic_a2d_lut(struct fpga_model* model, int y, int x, int type_idx,
// todo: the logic by which we auto-enable the direct // todo: the logic by which we auto-enable the direct
// output could have more cases, the O6 signal // output could have more cases, the O6 signal
// could go into the carry chain/XOR/CY, F7/F8, others? // could go into the carry chain/XOR/CY, F7/F8, others?
// O5 could go into carry chain/XOR/CY, others?
// We need to find out over time what makes sense for // We need to find out over time what makes sense for
// the caller. // the caller.
if (lut_5or6 == 6 if (lut_5or6 == 6
@ -486,6 +485,7 @@ int fdev_logic_a2d_lut(struct fpga_model* model, int y, int x, int type_idx,
&& dev->u.logic.a2d[lut_a2d].out_mux != MUX_O6) && dev->u.logic.a2d[lut_a2d].out_mux != MUX_O6)
dev->u.logic.a2d[lut_a2d].out_used = 1; dev->u.logic.a2d[lut_a2d].out_used = 1;
if (lut_5or6 == 5 if (lut_5or6 == 5
&& dev->u.logic.a2d[lut_a2d].cy0 != CY0_O5
&& dev->u.logic.a2d[lut_a2d].ff_mux != MUX_O5 && dev->u.logic.a2d[lut_a2d].ff_mux != MUX_O5
&& !dev->u.logic.a2d[lut_a2d].out_mux) && !dev->u.logic.a2d[lut_a2d].out_mux)
dev->u.logic.a2d[lut_a2d].out_mux = MUX_O5; dev->u.logic.a2d[lut_a2d].out_mux = MUX_O5;

View File

@ -6,6 +6,7 @@
// //
#include <stdarg.h> #include <stdarg.h>
#include <errno.h>
#include "helper.h" #include "helper.h"
#include "parts.h" #include "parts.h"
@ -177,6 +178,157 @@ fail:
return -1; return -1;
} }
uint64_t map_bits(uint64_t u64, int num_bits, int* dest_pos)
{
uint64_t result;
int i;
result = 0;
for (i = 0; i < num_bits; i++) {
if (u64 & (1ULL<<i))
result |= 1ULL<<(dest_pos[i]);
}
return result;
}
int bool_str2bits(const char* str, uint64_t* u64, int num_bits)
{
int i, j, bool_res, rc, vars[6];
if (num_bits != 32 && num_bits != 64) HERE();
*u64 = 0;
for (i = 0; i < num_bits; i++) {
for (j = 0; j < sizeof(vars)/sizeof(*vars); j++)
vars[j] = (i & (1<<j)) != 0;
bool_res = bool_eval(str, strlen(str), vars);
if (bool_res == -1) FAIL(EINVAL);
if (bool_res) *u64 |= 1ULL<<i;
}
return 0;
fail:
return rc;
}
typedef struct _minterm_entry
{
char a[6]; // 0=A1, 5=A6. value can be 0, 1 or 2 for 'removed'
int merged;
} minterm_entry;
const char* bool_bits2str(uint64_t u64, int num_bits)
{
// round 0 needs 64 entries
// round 1 (size2): 192
// round 2 (size4): 240
// round 3 (size8): 160
// round 4 (size16): 60
// round 5 (size32): 12
// round 6 (size64): 1
minterm_entry mt[7][256];
int mt_size[7];
int i, j, k, round, only_diff_bit;
int str_end, first_op, bit_width;
static char str[2048];
if (num_bits == 64)
bit_width = 6;
else if (num_bits == 32)
bit_width = 5;
else {
HERE();
return "0";
}
if (!u64) return "0";
if (u64 == 0xFFFFFFFFFFFFFFFFULL) return "1";
memset(mt, 0, sizeof(mt));
memset(mt_size, 0, sizeof(mt_size));
// set starting minterms
for (i = 0; i < num_bits; i++) {
if (u64 & (1ULL<<i)) {
for (j = 0; j < bit_width; j++) {
if (i&(1<<j))
mt[0][mt_size[0]].a[j] = 1;
}
mt_size[0]++;
}
}
// go through five rounds of merging
for (round = 1; round < 7; round++) {
for (i = 0; i < mt_size[round-1]; i++) {
for (j = i+1; j < mt_size[round-1]; j++) {
only_diff_bit = -1;
for (k = 0; k < bit_width; k++) {
if (mt[round-1][i].a[k] != mt[round-1][j].a[k]) {
if (only_diff_bit != -1) {
only_diff_bit = -1;
break;
}
only_diff_bit = k;
}
}
if (only_diff_bit != -1) {
char new_term[6];
for (k = 0; k < bit_width; k++)
new_term[k] =
(k == only_diff_bit) ? 2
: mt[round-1][i].a[k];
for (k = 0; k < mt_size[round]; k++) {
if (new_term[0] == mt[round][k].a[0]
&& new_term[1] == mt[round][k].a[1]
&& new_term[2] == mt[round][k].a[2]
&& new_term[3] == mt[round][k].a[3]
&& new_term[4] == mt[round][k].a[4]
&& new_term[5] == mt[round][k].a[5])
break;
}
if (k >= mt_size[round]) {
mt[round][mt_size[round]].a[0] = new_term[0];
mt[round][mt_size[round]].a[1] = new_term[1];
mt[round][mt_size[round]].a[2] = new_term[2];
mt[round][mt_size[round]].a[3] = new_term[3];
mt[round][mt_size[round]].a[4] = new_term[4];
mt[round][mt_size[round]].a[5] = new_term[5];
mt_size[round]++;
}
mt[round-1][i].merged = 1;
mt[round-1][j].merged = 1;
}
}
}
}
str_end = 0;
for (round = 0; round < 7; round++) {
for (i = 0; i < mt_size[round]; i++) {
if (!mt[round][i].merged) {
if (str_end)
str[str_end++] = '+';
first_op = 1;
for (j = 0; j < bit_width; j++) {
if (mt[round][i].a[j] != 2) {
if (!first_op)
str[str_end++] = '*';
if (!mt[round][i].a[j])
str[str_end++] = '~';
str[str_end++] = 'A';
str[str_end++] = '1' + j;
first_op = 0;
}
}
}
}
}
str[str_end] = 0;
// TODO: This could be further simplified, see Petrick's method.
// XOR don't simplify well, try A2@A3
return str;
}
int parse_boolexpr(const char* expr, uint64_t* lut) int parse_boolexpr(const char* expr, uint64_t* lut)
{ {
int i, j, result, vars[6]; int i, j, result, vars[6];
@ -198,36 +350,6 @@ int parse_boolexpr(const char* expr, uint64_t* lut)
return 0; return 0;
} }
void printf_lut6(const char* cfg)
{
uint64_t lut;
uint32_t first_major, second_major;
int i;
first_major = 0;
second_major = 0;
// todo: this is missing the different base_values, flip_b0 etc.
parse_boolexpr(cfg, &lut);
for (i = 0; i < 16; i++) {
if (lut & (1LL<<(i*4)))
first_major |= 1<<(i*2);
if (lut & (1LL<<(i*4+1)))
first_major |= 1<<(i*2+1);
if (lut & (1LL<<(i*4+2)))
second_major |= 1<<(i*2);
if (lut & (1LL<<(i*4+3)))
second_major |= 1<<(i*2+1);
}
printf("first_major 0x%X second_major 0x%X\n", first_major, second_major);
}
typedef struct _minterm_entry
{
char a[6]; // 0=A1, 5=A6. value can be 0, 1 or 2 for 'removed'
int merged;
} minterm_entry;
// bits is tested only for 32 and 64 // bits is tested only for 32 and 64
const char* lut2bool(const uint64_t lut, int bits, const char* lut2bool(const uint64_t lut, int bits,
int (*logic_base)[6], int flip_b0) int (*logic_base)[6], int flip_b0)
@ -574,6 +696,48 @@ void frame_set_u64(uint8_t* frame_d, uint64_t v)
frame_set_u32(frame_d+4, high_w); frame_set_u32(frame_d+4, high_w);
} }
uint64_t frame_get_lut64(const uint8_t* two_minors, int v32)
{
int off_in_frame, i;
uint32_t m0, m1;
uint64_t lut64;
off_in_frame = v32*4;
if (off_in_frame >= 64)
off_in_frame += XC6_HCLK_BYTES;
m0 = frame_get_u32(&two_minors[off_in_frame]);
m1 = frame_get_u32(&two_minors[FRAME_SIZE + off_in_frame]);
lut64 = 0;
for (i = 0; i < 32; i++) {
if (m0 & (1<<i)) lut64 |= 1ULL << (2*i);
if (m1 & (1<<i)) lut64 |= 1ULL << (2*i+1);
}
return lut64;
}
void frame_set_lut64(uint8_t* two_minors, int v32, uint64_t v)
{
int off_in_frame, i;
uint32_t m0, m1;
m0 = 0;
m1 = 0;
for (i = 0; i < 64; i++) {
if (v & (1ULL << i)) {
if (i%2)
m1 |= 1<<(i/2);
else
m0 |= 1<<(i/2);
}
}
off_in_frame = v32*4;
if (off_in_frame >= 64)
off_in_frame += XC6_HCLK_BYTES;
frame_set_u32(&two_minors[off_in_frame], m0);
frame_set_u32(&two_minors[FRAME_SIZE + off_in_frame], m1);
}
int printf_frames(const uint8_t* bits, int max_frames, int printf_frames(const uint8_t* bits, int max_frames,
int row, int major, int minor, int print_empty, int no_clock) int row, int major, int minor, int print_empty, int no_clock)
{ {

View File

@ -57,8 +57,11 @@ typedef struct _cfg_atom
int atom_found(char* bits, const cfg_atom_t* atom); int atom_found(char* bits, const cfg_atom_t* atom);
void atom_remove(char* bits, const cfg_atom_t* atom); void atom_remove(char* bits, const cfg_atom_t* atom);
uint64_t map_bits(uint64_t u64, int num_bits, int* dest_pos);
int bool_str2bits(const char* str, uint64_t* u64, int num_bits);
const char* bool_bits2str(uint64_t u64, int num_bits);
int parse_boolexpr(const char* expr, uint64_t* lut); int parse_boolexpr(const char* expr, uint64_t* lut);
void printf_lut6(const char* cfg);
// bits is tested only for 32 and 64 // bits is tested only for 32 and 64
const char* lut2bool(const uint64_t lut, int bits, const char* lut2bool(const uint64_t lut, int bits,
int (*logic_base)[6], int flip_b0); int (*logic_base)[6], int flip_b0);
@ -83,6 +86,12 @@ void frame_set_u16(uint8_t* frame_d, uint16_t v);
void frame_set_u32(uint8_t* frame_d, uint32_t v); void frame_set_u32(uint8_t* frame_d, uint32_t v);
void frame_set_u64(uint8_t* frame_d, uint64_t v); void frame_set_u64(uint8_t* frame_d, uint64_t v);
uint64_t frame_get_lut64(const uint8_t* two_minors, int v32);
// In a lut pair, LOW32 is lut5, HIGH32 is lut6.
#define ULL_LOW32(v) ((uint32_t) (((uint64_t)v) & 0xFFFFFFFFULL))
#define ULL_HIGH32(v) ((uint32_t) (((uint64_t)v) >> 32))
void frame_set_lut64(uint8_t* two_minors, int v32, uint64_t v);
// if row is negative, it's an absolute frame number and major and // if row is negative, it's an absolute frame number and major and
// minor are ignored // minor are ignored
int printf_frames(const uint8_t* bits, int max_frames, int row, int major, int printf_frames(const uint8_t* bits, int max_frames, int row, int major,

View File

@ -809,3 +809,42 @@ void free_xc6_routing_bitpos(struct xc6_routing_bitpos* bitpos)
{ {
free(bitpos); free(bitpos);
} }
void xc6_lut_bitmap(int lut_pos, int* map, int num_bits)
{
static const int xc6_lut_wiring[4][16] = {
// xm-m a; xm-m c;
{ 17, 19, 16, 18, 23, 21, 22, 20, 31, 29, 30, 28, 25, 27, 24, 26 },
// xm-m b; xm-m d;
{ 47, 45, 46, 44, 41, 43, 40, 42, 33, 35, 32, 34, 39, 37, 38, 36 },
// xm-x a; xm-x b; xl-l b; xl-l d; xl-x a; xl-x b;
{ 31, 29, 30, 28, 27, 25, 26, 24, 19, 17, 18, 16, 23, 21, 22, 20 },
// xm-x c; xm-x d; xl-l a; xl-l c; xl-x c; xl-x d;
{ 33, 35, 32, 34, 37, 39, 36, 38, 45, 47, 44, 46, 41, 43, 40, 42 }};
int map32[32];
int i;
// expand from 16 to 32 bit positions
for (i = 0; i < 16; i++) {
map32[i] = xc6_lut_wiring[lut_pos][i];
if (map32[i] < 32) {
if (map32[i] < 16) HERE();
map32[16+i] = map32[i]-16;
} else {
if (map32[i] > 47) HERE();
map32[16+i] = map32[i]+16;
}
}
// expand from 32 to 64 for either lut6 only or lut5/lut6 pair.
for (i = 0; i < 32; i++) {
if (num_bits == 32) {
map[i] = map32[i]%32;
map[32+i] = 32+map[i];
} else {
if (num_bits != 64) HERE();
map[i] = map32[i];
map[32+i] = (map[i]+32)%64;
}
}
}

View File

@ -97,6 +97,8 @@
#define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_8 0x0014000002000000 #define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_8 0x0014000002000000
#define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_12 0x00FC008802000000 #define XC6_IOB_OUTPUT_LVCMOS12_DRIVE_12 0x00FC008802000000
#define XC6_IOB_OUTPUT_SSTL2_I 0x0040001C00000000
#define XC6_IOB_IMUX_I_B 0x0000000000000400 #define XC6_IOB_IMUX_I_B 0x0000000000000400
#define XC6_IOB_O_PINW 0x0000000000000100 #define XC6_IOB_O_PINW 0x0000000000000100
#define XC6_IOB_SLEW_SLOW 0x0000000000000000 #define XC6_IOB_SLEW_SLOW 0x0000000000000000
@ -152,3 +154,26 @@ struct xc6_routing_bitpos
int get_xc6_routing_bitpos(struct xc6_routing_bitpos** bitpos, int* num_bitpos); int get_xc6_routing_bitpos(struct xc6_routing_bitpos** bitpos, int* num_bitpos);
void free_xc6_routing_bitpos(struct xc6_routing_bitpos* bitpos); void free_xc6_routing_bitpos(struct xc6_routing_bitpos* bitpos);
#define XC6_LMAP_XM_M_A 0
#define XC6_LMAP_XM_M_B 1
#define XC6_LMAP_XM_M_C 0
#define XC6_LMAP_XM_M_D 1
#define XC6_LMAP_XM_X_A 2
#define XC6_LMAP_XM_X_B 2
#define XC6_LMAP_XM_X_C 3
#define XC6_LMAP_XM_X_D 3
#define XC6_LMAP_XL_L_A 3
#define XC6_LMAP_XL_L_B 2
#define XC6_LMAP_XL_L_C 3
#define XC6_LMAP_XL_L_D 2
#define XC6_LMAP_XL_X_A 2
#define XC6_LMAP_XL_X_B 2
#define XC6_LMAP_XL_X_C 3
#define XC6_LMAP_XL_X_D 3
// num_bits must be 32 or 64. If it is 32, the lower
// 32 entries of map contain the bit positions for lut5,
// the upper 32 entries of map the ones for lut6.
// In either case 64 entries are written to map.
void xc6_lut_bitmap(int lut_pos, int* map, int num_bits);