preparing for some more lut work

This commit is contained in:
Wolfgang Spraul 2012-10-01 04:09:52 +02:00
parent 1a1b861956
commit fd21f8ce9d
9 changed files with 388 additions and 147 deletions

View File

@ -112,13 +112,13 @@ design_%.ftest: design_%.ffbd
@diff -u $(basename $@).fp $(basename $@).fb2f >$@ || true
%.fb2f: %.ff2b bit2fp
@./bit2fp $< 2>&1 >$@
@./bit2fp $< >$@ 2>&1
%.ff2b: %.fp fp2bit
@./fp2bit $< $@
design_%.fp: $$*
@./$(*F) 2>&1 >$@
@./$(*F) >$@ 2>&1
# autotest targets
@ -130,7 +130,7 @@ autotest_%.ftest: autotest_%.far
@diff -U 0 -I "^O #NODIFF" test.gold/$(*F).fao $< >$@ || true
autotest_%.fao: autotest fp2bit bit2fp
./autotest --test=$(*F) 2>&1 >$@
./autotest --test=$(*F) >$@ 2>&1
# compare testing targets

8
README
View File

@ -1,9 +1,9 @@
Introduction
fpgatools is a toolchain to program flexible programmable gate arrays
fpgatools is a toolchain to program field-programmable gate arrays
(FPGAs). The only supported chip at this time is the xc6slx9, a cheap
(ca. 10 USD) but powerful 45nm-generation chip with about 2400 LUTs,
(ca. 7 USD) but powerful 45nm-generation chip with 5720 6-input LUTs,
block ram and multiply-accumulate devices.
The principles of fpgatools are:
The long-term goals of fpgatools are:
*) reach the maximum physical performance of the chip
*) fast development cycles
@ -59,6 +59,8 @@ Design Principles
TODO
short-term (1 month):
* add lut_encoding autotest for lut6 and lut5 in a-d position
of x(m), x(l), l and m devs
* example: blinking_led
* example: counter (including clock, jtag)
* support reading iologic switches

View File

@ -715,7 +715,7 @@ static void print_ramb16_cfg(ramb16_cfg_t* cfg)
printf("}\n");
}
static void printf_routing_2minors(uint8_t* bits, int row, int major,
static void printf_routing_2minors(const uint8_t* bits, int row, int major,
int even_minor)
{
int y, i, hclk;
@ -742,7 +742,7 @@ static void printf_routing_2minors(uint8_t* bits, int row, int major,
}
}
static void printf_v64_mi20(uint8_t* bits, int row, int major)
static void printf_v64_mi20(const uint8_t* bits, int row, int major)
{
int y, i, hclk;
uint64_t u64;
@ -761,88 +761,199 @@ static void printf_v64_mi20(uint8_t* bits, int row, int major)
}
}
static int dump_bits(struct fpga_config* cfg)
static void printf_lut(const uint8_t* bits, int row, int major,
int minor, int v32_i)
{
int row, major, minor, i, j, off, offset_in_frame;
int i, byte_off_in_frame;
uint32_t u32;
uint64_t u64;
char bit_str[64];
// type0
off = 0;
for (row = 0; row < 4; row++) {
for (major = 0; major < 18; major++) {
// todo: the macc/bram/logic special cases can be removed
if (get_major_type(cfg->reg[cfg->idcode_reg].int_v,
major) == MAJ_MACC) {
int last_extra_minor;
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);
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);
if (!row || row == 3)
last_extra_minor = 23;
else
last_extra_minor = 21;
minor = 0;
while (minor <= last_extra_minor) {
minor += printf_frames(&cfg->bits.d[off
+minor*130], 31 - minor, row,
major, minor, /*print_empty*/ 0);
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);
}
}
// clock
for (; minor < 24; minor++)
printf_clock(&cfg->bits.d[off+minor*130],
row, major, minor);
static int dump_maj_zero(const uint8_t* bits, int row, int major)
{
int minor;
for (i = 0; i < 4; i++) {
for (minor = last_extra_minor+1; minor < 24;
minor++) {
for (j = 0; j < 256; j++) {
if (frame_get_bit(&cfg->bits.d[off+minor*130], i*256 + ((i>=2)?16:0) + j))
printf("r%i ma%i dsp i%i mi%i bit %i\n", row, major, i, minor, i*256+j);
}
}
}
} else if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major) == MAJ_LOGIC_XM) {
// clock
for (minor = 0; minor < 31; minor++)
printf_clock(
&cfg->bits.d[off+minor*130],
row, major, minor);
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
for (minor = 0; 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);
return 0;
}
// bitwise
minor = 0;
while (minor < 31) {
minor += printf_frames(&cfg->bits.d[off
+minor*130], 31 - minor,
row, major, minor, /*print_empty*/ 0);
}
static int dump_maj_left(const uint8_t* bits, int row, int major)
{
int minor;
// 0:20 routing minor pairs
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
for (minor = 0; 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);
return 0;
}
static int dump_maj_right(const uint8_t* bits, int row, int major)
{
int minor;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
for (minor = 0; 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);
return 0;
}
static int dump_maj_center(const uint8_t* bits, int row, int major)
{
int minor, i;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs
for (i = 0; i < 10; i++)
printf_routing_2minors(&cfg->bits.d[
off+i*2*FRAME_SIZE], row, major, i*2);
printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string
printf_v64_mi20(&cfg->bits.d[
off+20*FRAME_SIZE], row, major);
} else if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major) == MAJ_BRAM) {
ramb16_cfg_t ramb16_cfg[4];
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
// minors 0..22
minor = 0;
while (minor < 23) {
minor += printf_frames(&cfg->bits.d[off
+minor*130], 23 - minor, row,
major, minor, /*print_empty*/ 0);
// L devices
for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 21, i*2);
printf_lut(bits, row, major, 23, i*2);
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);
return 0;
}
static int dump_maj_logic_xm(const uint8_t* bits, int row, int major)
{
int minor, i;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs
for (i = 0; i < 10; i++)
printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
// todo: some logic device configuration bits are also in mi20
// todo: the top and bottom two luts should be skipped in !no_io cols
// M devices
for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 21, i*2);
printf_lut(bits, row, major, 21, i*2+1);
}
printf_frames(&bits[23*FRAME_SIZE], /*max_frames*/ 1,
row, major, 23, /*print_empty*/ 0, /*no_clock*/ 1);
for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 24, i*2);
printf_lut(bits, row, major, 24, i*2+1);
}
// X devices
printf_frames(&bits[26*FRAME_SIZE], /*max_frames*/ 1,
row, major, 26, /*print_empty*/ 0, /*no_clock*/ 1);
for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 27, i*2);
printf_lut(bits, row, major, 29, i*2);
printf_lut(bits, row, major, 27, i*2+1);
printf_lut(bits, row, major, 29, i*2+1);
}
return 0;
}
static int dump_maj_logic_xl(const uint8_t* bits, int row, int major)
{
int minor, i;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs
for (i = 0; i < 10; i++)
printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
// L devices
for (i = 0; i < 16; i++) {
printf_lut(bits, row, major, 21, i*2);
printf_lut(bits, row, major, 23, i*2);
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);
return 0;
}
static int dump_maj_bram(const uint8_t* bits, int row, int major)
{
ramb16_cfg_t ramb16_cfg[4];
int minor, i, j, offset_in_frame;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs
for (i = 0; i < 10; i++)
printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
printf_frames(&bits[21*FRAME_SIZE], /*max_frames*/ 1,
row, major, 21, /*print_empty*/ 0, /*no_clock*/ 1);
printf_frames(&bits[22*FRAME_SIZE], /*max_frames*/ 1,
row, major, 22, /*print_empty*/ 0, /*no_clock*/ 1);
// minors 23&24
printf_clock(&cfg->bits.d[off+23*130], row, major, 23);
printf_clock(&cfg->bits.d[off+24*130], row, major, 24);
for (i = 0; i < 4; i++) {
offset_in_frame = i*32;
if (offset_in_frame >= 64)
offset_in_frame += 2;
for (j = 0; j < 32; j++) {
ramb16_cfg[i].byte[j] = cfg->bits.d[off+23*130+offset_in_frame+j];
ramb16_cfg[i].byte[j+32] = cfg->bits.d[off+24*130+offset_in_frame+j];
ramb16_cfg[i].byte[j] = bits[23*130+offset_in_frame+j];
ramb16_cfg[i].byte[j+32] = bits[24*130+offset_in_frame+j];
}
}
for (i = 0; i < 4; i++) {
@ -856,20 +967,77 @@ static int dump_bits(struct fpga_config* cfg)
row, major, i);
print_ramb16_cfg(&ramb16_cfg[i]);
}
} else {
int major_minors =
get_major_minors(cfg->reg[cfg->idcode_reg].int_v, major);
minor = 0;
while (minor < major_minors) {
minor += printf_frames(&cfg->bits.d[off
+minor*130], major_minors - minor,
row, major, minor, /*print_empty*/ 0);
return 0;
}
static int dump_maj_macc(const uint8_t* bits, int row, int major)
{
int minor, i;
for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
// 0:19 routing minor pairs
for (i = 0; i < 10; i++)
printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string
printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
for (minor = 21; 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);
return 0;
}
static int dump_bits(struct fpga_config* cfg)
{
int row, major, off, rc;
// type0
for (major = 0; major <= get_rightside_major(XC6SLX9); major++) {
for (row = 3; row >= 0; row--) {
off = (row*get_frames_per_row(XC6SLX9) + get_major_framestart(XC6SLX9, major)) * FRAME_SIZE;
switch (get_major_type(cfg->reg[cfg->idcode_reg].int_v, major)) {
case MAJ_ZERO:
rc = dump_maj_zero(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_LEFT:
rc = dump_maj_left(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_RIGHT:
rc = dump_maj_right(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_CENTER:
rc = dump_maj_center(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_LOGIC_XM:
rc = dump_maj_logic_xm(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_LOGIC_XL:
rc = dump_maj_logic_xl(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_BRAM:
rc = dump_maj_bram(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
case MAJ_MACC:
rc = dump_maj_macc(&cfg->bits.d[off], row, major);
if (rc) FAIL(rc);
break;
default: HERE(); break;
}
}
off += get_major_minors(XC6SLX9, major) * FRAME_SIZE;
}
}
return 0;
fail:
return rc;
}
static int dump_bram(struct fpga_config* cfg)

View File

@ -399,6 +399,15 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
break;
case 0: break; default: FAIL(EINVAL);
}
switch (cfg->a2d[j].cy0) {
case CY0_X:
fprintf(f, "%s %c_cy0 X\n", pref, 'A'+j);
break;
case CY0_O5:
fprintf(f, "%s %c_cy0 O5\n", pref, 'A'+j);
break;
case 0: break; default: FAIL(EINVAL);
}
}
switch (cfg->clk_inv) {
case CLKINV_B:
@ -431,6 +440,20 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
break;
case 0: break; default: FAIL(EINVAL);
}
if (cfg->cout_used)
fprintf(f, "%s cout_used\n", pref);
switch (cfg->precyinit) {
case PRECYINIT_0:
fprintf(f, "%s precyinit 0\n", pref);
break;
case PRECYINIT_1:
fprintf(f, "%s precyinit 1\n", pref);
break;
case PRECYINIT_AX:
fprintf(f, "%s precyinit AX\n", pref);
break;
case 0: break; default: FAIL(EINVAL);
}
}
return 0;
fail:
@ -463,6 +486,10 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
dev->u.logic.sr_used = 1;
goto inst_1;
}
if (!str_cmp(w1, w1_len, "cout_used", ZTERM)) {
dev->u.logic.cout_used = 1;
goto inst_1;
}
// The remaining attributes all require 2 words.
if (w2_len < 1) return 0;
@ -512,15 +539,15 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (!str_cmp(w2, w2_len, "O6", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_O6;
if (!str_cmp(w2, w2_len, "O5", ZTERM))
else if (!str_cmp(w2, w2_len, "O5", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_O5;
if (!str_cmp(w2, w2_len, "5Q", ZTERM))
else if (!str_cmp(w2, w2_len, "5Q", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_5Q;
if (!str_cmp(w2, w2_len, "F7", ZTERM))
else if (!str_cmp(w2, w2_len, "F7", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_F7;
if (!str_cmp(w2, w2_len, "CY", ZTERM))
else if (!str_cmp(w2, w2_len, "CY", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_CY;
if (!str_cmp(w2, w2_len, "XOR", ZTERM))
else if (!str_cmp(w2, w2_len, "XOR", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_XOR;
else return 0;
goto inst_2;
@ -529,15 +556,24 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (!str_cmp(w2, w2_len, "OR2L", ZTERM))
dev->u.logic.a2d[i].ff = FF_OR2L;
if (!str_cmp(w2, w2_len, "AND2L", ZTERM))
else if (!str_cmp(w2, w2_len, "AND2L", ZTERM))
dev->u.logic.a2d[i].ff = FF_AND2L;
if (!str_cmp(w2, w2_len, "LATCH", ZTERM))
else if (!str_cmp(w2, w2_len, "LATCH", ZTERM))
dev->u.logic.a2d[i].ff = FF_LATCH;
if (!str_cmp(w2, w2_len, "FF", ZTERM))
else if (!str_cmp(w2, w2_len, "FF", ZTERM))
dev->u.logic.a2d[i].ff = FF_FF;
else return 0;
goto inst_2;
}
snprintf(cmp_str, sizeof(cmp_str), "%c_cy0", 'A'+i);
if (!str_cmp(w1, w1_len, cmp_str, ZTERM)) {
if (!str_cmp(w2, w2_len, "X", ZTERM))
dev->u.logic.a2d[i].cy0 = CY0_X;
else if (!str_cmp(w2, w2_len, "O5", ZTERM))
dev->u.logic.a2d[i].cy0 = CY0_O5;
else return 0;
goto inst_2;
}
}
if (!str_cmp(w1, w1_len, "clk", ZTERM)) {
if (!str_cmp(w2, w2_len, "CLK_B", ZTERM))
@ -563,6 +599,16 @@ static int read_LOGIC_attr(struct fpga_model* model, int y, int x, int type_idx,
else return 0;
goto inst_2;
}
if (!str_cmp(w1, w1_len, "precyinit", ZTERM)) {
if (!str_cmp(w2, w2_len, "0", ZTERM))
dev->u.logic.precyinit = PRECYINIT_0;
else if (!str_cmp(w2, w2_len, "1", ZTERM))
dev->u.logic.precyinit = PRECYINIT_1;
else if (!str_cmp(w2, w2_len, "AX", ZTERM))
dev->u.logic.precyinit = PRECYINIT_AX;
else return 0;
goto inst_2;
}
return 0;
inst_1:
dev->instantiated = 1;

View File

@ -463,14 +463,14 @@ void printf_ramb16_data(uint8_t* bits, int inpos)
}
}
int is_empty(uint8_t* d, int l)
int is_empty(const uint8_t* d, int l)
{
while (--l >= 0)
if (d[l]) return 0;
return 1;
}
int count_bits(uint8_t* d, int l)
int count_bits(const uint8_t* d, int l)
{
int bits = 0;
while (--l >= 0) {
@ -486,7 +486,7 @@ int count_bits(uint8_t* d, int l)
return bits;
}
int frame_get_bit(uint8_t* frame_d, int bit)
int frame_get_bit(const uint8_t* frame_d, int bit)
{
uint8_t v = 1<<(7-(bit%8));
return (frame_d[(bit/16)*2 + !((bit/8)%2)] & v) != 0;
@ -504,7 +504,7 @@ void frame_set_bit(uint8_t* frame_d, int bit)
frame_d[(bit/16)*2 + !((bit/8)%2)] |= v;
}
uint8_t frame_get_u8(uint8_t* frame_d)
uint8_t frame_get_u8(const uint8_t* frame_d)
{
uint8_t v = 0;
int i;
@ -513,7 +513,7 @@ uint8_t frame_get_u8(uint8_t* frame_d)
return v;
}
uint16_t frame_get_u16(uint8_t* frame_d)
uint16_t frame_get_u16(const uint8_t* frame_d)
{
uint16_t high_b, low_b;
high_b = frame_get_u8(frame_d);
@ -521,7 +521,7 @@ uint16_t frame_get_u16(uint8_t* frame_d)
return (high_b << 8) | low_b;
}
uint32_t frame_get_u32(uint8_t* frame_d)
uint32_t frame_get_u32(const uint8_t* frame_d)
{
uint32_t high_w, low_w;
low_w = frame_get_u16(frame_d);
@ -529,7 +529,7 @@ uint32_t frame_get_u32(uint8_t* frame_d)
return (high_w << 16) | low_w;
}
uint64_t frame_get_u64(uint8_t* frame_d)
uint64_t frame_get_u64(const uint8_t* frame_d)
{
uint64_t high_w, low_w;
low_w = frame_get_u32(frame_d);
@ -575,8 +575,8 @@ void frame_set_u64(uint8_t* frame_d, uint64_t v)
frame_set_u32(frame_d+4, high_w);
}
int printf_frames(uint8_t* bits, int max_frames,
int row, int major, int minor, int print_empty)
int printf_frames(const uint8_t* bits, int max_frames,
int row, int major, int minor, int print_empty, int no_clock)
{
int i, i_without_clk;
char prefix[128], suffix[128];
@ -599,10 +599,13 @@ int printf_frames(uint8_t* bits, int max_frames,
}
return i;
}
if (count_bits(bits, 130) <= 32) {
// value 128 chosen randomly for readability to decide
// between printing individual bits or a hex block.
if (count_bits(bits, 130) <= 128) {
for (i = 0; i < FRAME_SIZE*8; i++) {
if (!frame_get_bit(bits, i)) continue;
if (i >= 512 && i < 528) { // hclk
if (!no_clock)
printf("%sbit %i\n", prefix, i);
continue;
}
@ -623,7 +626,7 @@ int printf_frames(uint8_t* bits, int max_frames,
return 1;
}
void printf_clock(uint8_t* frame, int row, int major, int minor)
void printf_clock(const uint8_t* frame, int row, int major, int minor)
{
int i;
for (i = 0; i < 16; i++) {
@ -649,7 +652,7 @@ int clb_empty(uint8_t* maj_bits, int idx)
return 1;
}
void printf_extrabits(uint8_t* maj_bits, int start_minor, int num_minors,
void printf_extrabits(const uint8_t* maj_bits, int start_minor, int num_minors,
int start_bit, int num_bits, int row, int major)
{
int minor, bit;
@ -663,19 +666,19 @@ void printf_extrabits(uint8_t* maj_bits, int start_minor, int num_minors,
}
}
uint64_t read_lut64(uint8_t* two_minors, int off_in_frame)
uint64_t read_lut64(const uint8_t* two_minors, int bit_off_in_frame)
{
uint64_t lut64 = 0;
int j;
for (j = 0; j < 16; j++) {
if (frame_get_bit(two_minors, off_in_frame+j*2))
if (frame_get_bit(two_minors, bit_off_in_frame+j*2))
lut64 |= 1LL << (j*4);
if (frame_get_bit(two_minors, off_in_frame+(j*2)+1))
if (frame_get_bit(two_minors, bit_off_in_frame+(j*2)+1))
lut64 |= 1LL << (j*4+1);
if (frame_get_bit(&two_minors[130], off_in_frame+j*2))
if (frame_get_bit(&two_minors[130], bit_off_in_frame+j*2))
lut64 |= 1LL << (j*4+2);
if (frame_get_bit(&two_minors[130], off_in_frame+(j*2)+1))
if (frame_get_bit(&two_minors[130], bit_off_in_frame+(j*2)+1))
lut64 |= 1LL << (j*4+3);
}
return lut64;

View File

@ -66,17 +66,17 @@ 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 is_empty(const uint8_t* d, int l);
int count_bits(const uint8_t* d, int l);
int frame_get_bit(uint8_t* frame_d, int bit);
int frame_get_bit(const uint8_t* frame_d, int bit);
void frame_clear_bit(uint8_t* frame_d, int bit);
void frame_set_bit(uint8_t* frame_d, int bit);
uint8_t frame_get_u8(uint8_t* frame_d);
uint16_t frame_get_u16(uint8_t* frame_d);
uint32_t frame_get_u32(uint8_t* frame_d);
uint64_t frame_get_u64(uint8_t* frame_d);
uint8_t frame_get_u8(const uint8_t* frame_d);
uint16_t frame_get_u16(const uint8_t* frame_d);
uint32_t frame_get_u32(const uint8_t* frame_d);
uint64_t frame_get_u64(const uint8_t* frame_d);
void frame_set_u8(uint8_t* frame_d, uint8_t v);
void frame_set_u16(uint8_t* frame_d, uint16_t v);
@ -85,13 +85,13 @@ void frame_set_u64(uint8_t* frame_d, uint64_t v);
// 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 printf_frames(const uint8_t* bits, int max_frames, int row, int major,
int minor, int print_empty, int no_clock);
void printf_clock(const uint8_t* frame, int row, int major, int minor);
int clb_empty(uint8_t* maj_bits, int idx);
void printf_extrabits(uint8_t* maj_bits, int start_minor, int num_minors,
void printf_extrabits(const 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);
uint64_t read_lut64(const uint8_t* two_minors, int bit_off_in_frame);
void write_lut64(uint8_t* two_minors, int off_in_frame, uint64_t u64);
int get_vm_mb(void);

View File

@ -412,9 +412,11 @@ enum { LUT_A = 0, LUT_B, LUT_C, LUT_D }; // offset into a2d[]
enum { FF_SRINIT0 = 1, FF_SRINIT1 };
enum { MUX_O6 = 1, MUX_O5, MUX_5Q, MUX_X, MUX_F7, MUX_CY, MUX_XOR };
enum { FF_OR2L = 1, FF_AND2L, FF_LATCH, FF_FF };
enum { CY0_X = 1, CY0_O5 };
enum { CLKINV_B = 1, CLKINV_CLK };
enum { SYNCATTR_SYNC = 1, SYNCATTR_ASYNC };
enum { WEMUX_WE = 1, WEMUX_CE };
enum { PRECYINIT_0 = 1, PRECYINIT_1, PRECYINIT_AX };
#define MAX_LUT_LEN 2048
@ -427,6 +429,7 @@ struct fpgadev_logic_a2d
int ff_srinit; // SRINIT0, SRINIT1
int out_mux; // O6, O5, 5Q, F7, CY, XOR
int ff; // OR2L, AND2L, LATCH, FF
int cy0; // X, O5
};
struct fpgadev_logic
@ -437,6 +440,8 @@ struct fpgadev_logic
int ce_used;
int sr_used;
int we_mux; // WEMUX_WE, WEMUX_CE
int cout_used;
int precyinit; // PRECYINIT_0, PRECYINIT_1, PRECYINIT_AX
};
//

View File

@ -159,6 +159,21 @@ int get_rightside_major(int idcode)
return XC6_SLX9_RIGHTMOST_MAJOR;
}
int get_major_framestart(int idcode, int major)
{
int i, frame_count;
frame_count = 0;
for (i = 0; i < major; i++)
frame_count += get_major_minors(idcode, i);
return frame_count;
}
int get_frames_per_row(int idcode)
{
return get_major_framestart(idcode, get_rightside_major(idcode)+1);
}
//
// routing switches
//

View File

@ -81,6 +81,8 @@ enum major_type get_major_type(int idcode, int major);
#define XC6_SLX9_RIGHTMOST_MAJOR 17
int get_rightside_major(int idcode);
int get_major_framestart(int idcode, int major);
int get_frames_per_row(int idcode);
int get_num_iobs(int idcode);
const char* get_iob_sitename(int idcode, int idx);