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
http://gtkwave.sourceforge.net
cores
https://github.com/openrisc/mor1kx
https://github.com/milkymist
Fedora Electronic Lab tool overview
http://spins.fedoraproject.org/fel/#portfolio
http://chitlesh.fedorapeople.org/FEL/list.html
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)
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
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)
{
int idx_enum[] = { DEV_LOG_M_OR_L, DEV_LOG_X };
int x_enum[] = { /*xm*/ 13, /* center-xl*/ 22, /*xl*/ 39 };
int y, x_i, i, j, k, lut_str_len, rc;
// The center column (x==22 on a xc6slx9) is a regular XL column
// 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;
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;
@ -1135,36 +1135,35 @@ static int test_lut_encoding(struct test_state* tstate)
if (rc) FAIL(rc);
}
// lut6 and lut5 pairs
i = 0;
while (lut5_parents[i]) {
rc = test_lut(tstate, y, x_enum[x_i], idx_enum[type_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],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ "0");
lut,
/*lut6*/ pf("(A6+~A6)*%s", lut_str),
/*lut5*/ lut_str);
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],
lut, /*lut6*/ lut5_parents[i], /*lut5*/ "1");
lut, /*lut6*/ pf("(A6+~A6)*%s", lut_str),
/*lut5*/ lut_str);
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
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) {
printf_help(argv[0], available_tests);
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,
int minor, int v32_i)
{
int i, byte_off_in_frame;
uint32_t u32;
uint64_t u64;
char bit_str[64];
uint64_t u64;
int i, num_on_bits;
byte_off_in_frame = v32_i*4;
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);
u64 = frame_get_lut64(&bits[minor*FRAME_SIZE], v32_i);
if (u64) {
for (i = 0; i < 64; i++)
bit_str[i] = (u64 & (1ULL << i)) ? '1' : '0';
printf("r%i ma%i v32_%02i mip%i_lut %.64s\n", row,
major, v32_i, minor, bit_str);
u32 = frame_get_u32(&bits[minor*FRAME_SIZE + byte_off_in_frame]);
for (i = 0; i < 32; i++)
bit_str[i] = (u32 & (1 << i)) ? '1' : '0';
printf("r%i ma%i v32_%02i mi%i_f32 %.32s\n", row, major,
v32_i, minor, bit_str);
u32 = frame_get_u32(&bits[(minor+1)*FRAME_SIZE + byte_off_in_frame]);
for (i = 0; i < 32; i++)
bit_str[i] = (u32 & (1 << i)) ? '1' : '0';
printf("r%i ma%i v32_%02i mi%i_f32 %.32s\n", row, major,
v32_i, minor+1, bit_str);
num_on_bits = 0;
for (i = 0; i < 64; i++) {
if (u64 & (1ULL << i))
num_on_bits++;
}
if (num_on_bits < 5) {
printf("r%i ma%02i v32_%02i mip%02i_lut", row,
major, v32_i, minor);
for (i = 0; i < 64; i++) {
if (u64 & (1ULL << i))
printf(" b%i", i);
}
printf("\n");
} else {
for (i = 0; i < 64; i++)
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;
if (get_major_minors(XC6SLX9, major) != 31) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, 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, 23, i*2+1);
}
for (minor = 25; minor < get_major_minors(XC6SLX9, major); minor++)
printf_frames(&bits[minor*FRAME_SIZE], /*max_frames*/ 1,
row, major, minor, /*print_empty*/ 0, /*no_clock*/ 1);
printf_frames(&bits[25*FRAME_SIZE], /*max_frames*/ 1,
row, major, 25, /*print_empty*/ 0, /*no_clock*/ 1);
// X devices
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;
}
@ -861,6 +869,8 @@ static int dump_maj_logic_xm(const uint8_t* bits, int row, int major)
{
int minor, i;
if (get_major_minors(XC6SLX9, major) != 31) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, 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;
if (get_major_minors(XC6SLX9, major) != 30) HERE();
for (minor = 0; minor < get_major_minors(XC6SLX9, 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, 23, i*2+1);
}
for (minor = 25; minor < get_major_minors(XC6SLX9, major); minor++)
printf_frames(&bits[minor*FRAME_SIZE], /*max_frames*/ 1,
row, major, minor, /*print_empty*/ 0, /*no_clock*/ 1);
printf_frames(&bits[25*FRAME_SIZE], /*max_frames*/ 1,
row, major, 25, /*print_empty*/ 0, /*no_clock*/ 1);
// X devices
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;
}

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
// output could have more cases, the O6 signal
// 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
// the caller.
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_used = 1;
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].out_mux)
dev->u.logic.a2d[lut_a2d].out_mux = MUX_O5;

View File

@ -6,6 +6,7 @@
//
#include <stdarg.h>
#include <errno.h>
#include "helper.h"
#include "parts.h"
@ -177,6 +178,157 @@ fail:
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 i, j, result, vars[6];
@ -198,36 +350,6 @@ int parse_boolexpr(const char* expr, uint64_t* lut)
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
const char* lut2bool(const uint64_t lut, int bits,
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);
}
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 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);
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);
void printf_lut6(const char* cfg);
// bits is tested only for 32 and 64
const char* lut2bool(const uint64_t lut, int bits,
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_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
// minor are ignored
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);
}
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_12 0x00FC008802000000
#define XC6_IOB_OUTPUT_SSTL2_I 0x0040001C00000000
#define XC6_IOB_IMUX_I_B 0x0000000000000400
#define XC6_IOB_O_PINW 0x0000000000000100
#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);
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);