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

8
README
View File

@ -1,9 +1,9 @@
Introduction 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 (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. 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 *) reach the maximum physical performance of the chip
*) fast development cycles *) fast development cycles
@ -59,6 +59,8 @@ Design Principles
TODO TODO
short-term (1 month): 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: blinking_led
* example: counter (including clock, jtag) * example: counter (including clock, jtag)
* support reading iologic switches * support reading iologic switches

View File

@ -715,7 +715,7 @@ static void print_ramb16_cfg(ramb16_cfg_t* cfg)
printf("}\n"); 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 even_minor)
{ {
int y, i, hclk; 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; int y, i, hclk;
uint64_t u64; 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 byte_off_in_frame = v32_i*4;
off = 0; if (byte_off_in_frame >= 64)
for (row = 0; row < 4; row++) { byte_off_in_frame += XC6_HCLK_BYTES;
for (major = 0; major < 18; major++) { u64 = read_lut64(&bits[minor*FRAME_SIZE], byte_off_in_frame*8);
// todo: the macc/bram/logic special cases can be removed if (u64) {
if (get_major_type(cfg->reg[cfg->idcode_reg].int_v, for (i = 0; i < 64; i++)
major) == MAJ_MACC) { bit_str[i] = (u64 & (1ULL << i)) ? '1' : '0';
int last_extra_minor; printf("r%i ma%i v32_%02i mip%i_lut %.64s\n", row,
major, v32_i, minor, bit_str);
if (!row || row == 3) u32 = frame_get_u32(&bits[minor*FRAME_SIZE + byte_off_in_frame]);
last_extra_minor = 23; for (i = 0; i < 32; i++)
else bit_str[i] = (u32 & (1 << i)) ? '1' : '0';
last_extra_minor = 21; printf("r%i ma%i v32_%02i mi%i_f32 %.32s\n", row, major,
minor = 0; v32_i, minor, bit_str);
while (minor <= last_extra_minor) {
minor += printf_frames(&cfg->bits.d[off u32 = frame_get_u32(&bits[(minor+1)*FRAME_SIZE + byte_off_in_frame]);
+minor*130], 31 - minor, row, for (i = 0; i < 32; i++)
major, minor, /*print_empty*/ 0); 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 static int dump_maj_zero(const uint8_t* bits, int row, int major)
for (; minor < 24; minor++) {
printf_clock(&cfg->bits.d[off+minor*130], int minor;
row, major, minor);
for (i = 0; i < 4; i++) { for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
for (minor = last_extra_minor+1; minor < 24; printf_clock(&bits[minor*FRAME_SIZE], row, major, minor);
minor++) { for (minor = 0; minor < get_major_minors(XC6SLX9, major); minor++)
for (j = 0; j < 256; j++) { printf_frames(&bits[minor*FRAME_SIZE], /*max_frames*/ 1,
if (frame_get_bit(&cfg->bits.d[off+minor*130], i*256 + ((i>=2)?16:0) + j)) row, major, minor, /*print_empty*/ 0, /*no_clock*/ 1);
printf("r%i ma%i dsp i%i mi%i bit %i\n", row, major, i, minor, i*256+j); return 0;
} }
}
}
} 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);
// bitwise static int dump_maj_left(const uint8_t* bits, int row, int major)
minor = 0; {
while (minor < 31) { int minor;
minor += printf_frames(&cfg->bits.d[off
+minor*130], 31 - minor,
row, major, minor, /*print_empty*/ 0);
}
// 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++) for (i = 0; i < 10; i++)
printf_routing_2minors(&cfg->bits.d[ printf_routing_2minors(&bits[i*2*FRAME_SIZE], row, major, i*2);
off+i*2*FRAME_SIZE], row, major, i*2);
// mi20 as 64-char 0/1 string // mi20 as 64-char 0/1 string
printf_v64_mi20(&cfg->bits.d[ printf_v64_mi20(&bits[20*FRAME_SIZE], row, major);
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];
// minors 0..22 // L devices
minor = 0; for (i = 0; i < 16; i++) {
while (minor < 23) { printf_lut(bits, row, major, 21, i*2);
minor += printf_frames(&cfg->bits.d[off printf_lut(bits, row, major, 23, i*2);
+minor*130], 23 - minor, row, printf_lut(bits, row, major, 21, i*2+1);
major, minor, /*print_empty*/ 0); 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 // 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++) { for (i = 0; i < 4; i++) {
offset_in_frame = i*32; offset_in_frame = i*32;
if (offset_in_frame >= 64) if (offset_in_frame >= 64)
offset_in_frame += 2; offset_in_frame += 2;
for (j = 0; j < 32; j++) { 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] = bits[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+32] = bits[24*130+offset_in_frame+j];
} }
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@ -856,20 +967,77 @@ static int dump_bits(struct fpga_config* cfg)
row, major, i); row, major, i);
print_ramb16_cfg(&ramb16_cfg[i]); print_ramb16_cfg(&ramb16_cfg[i]);
} }
} else { return 0;
int major_minors = }
get_major_minors(cfg->reg[cfg->idcode_reg].int_v, major);
minor = 0; static int dump_maj_macc(const uint8_t* bits, int row, int major)
while (minor < major_minors) { {
minor += printf_frames(&cfg->bits.d[off int minor, i;
+minor*130], major_minors - minor,
row, major, minor, /*print_empty*/ 0); 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; return 0;
fail:
return rc;
} }
static int dump_bram(struct fpga_config* cfg) 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; break;
case 0: break; default: FAIL(EINVAL); 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) { switch (cfg->clk_inv) {
case CLKINV_B: case CLKINV_B:
@ -431,6 +440,20 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model,
break; break;
case 0: break; default: FAIL(EINVAL); 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; return 0;
fail: 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; dev->u.logic.sr_used = 1;
goto inst_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. // The remaining attributes all require 2 words.
if (w2_len < 1) return 0; 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(w1, w1_len, cmp_str, ZTERM)) {
if (!str_cmp(w2, w2_len, "O6", ZTERM)) if (!str_cmp(w2, w2_len, "O6", ZTERM))
dev->u.logic.a2d[i].out_mux = MUX_O6; 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; 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; 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; 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; 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; dev->u.logic.a2d[i].out_mux = MUX_XOR;
else return 0; else return 0;
goto inst_2; 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(w1, w1_len, cmp_str, ZTERM)) {
if (!str_cmp(w2, w2_len, "OR2L", ZTERM)) if (!str_cmp(w2, w2_len, "OR2L", ZTERM))
dev->u.logic.a2d[i].ff = FF_OR2L; 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; 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; 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; dev->u.logic.a2d[i].ff = FF_FF;
else return 0; else return 0;
goto inst_2; 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(w1, w1_len, "clk", ZTERM)) {
if (!str_cmp(w2, w2_len, "CLK_B", 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; else return 0;
goto inst_2; 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; return 0;
inst_1: inst_1:
dev->instantiated = 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) while (--l >= 0)
if (d[l]) return 0; if (d[l]) return 0;
return 1; return 1;
} }
int count_bits(uint8_t* d, int l) int count_bits(const uint8_t* d, int l)
{ {
int bits = 0; int bits = 0;
while (--l >= 0) { while (--l >= 0) {
@ -486,7 +486,7 @@ int count_bits(uint8_t* d, int l)
return bits; 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)); uint8_t v = 1<<(7-(bit%8));
return (frame_d[(bit/16)*2 + !((bit/8)%2)] & v) != 0; 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; 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; uint8_t v = 0;
int i; int i;
@ -513,7 +513,7 @@ uint8_t frame_get_u8(uint8_t* frame_d)
return v; 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; uint16_t high_b, low_b;
high_b = frame_get_u8(frame_d); 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; 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; uint32_t high_w, low_w;
low_w = frame_get_u16(frame_d); 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; 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; uint64_t high_w, low_w;
low_w = frame_get_u32(frame_d); 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); frame_set_u32(frame_d+4, high_w);
} }
int printf_frames(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 row, int major, int minor, int print_empty, int no_clock)
{ {
int i, i_without_clk; int i, i_without_clk;
char prefix[128], suffix[128]; char prefix[128], suffix[128];
@ -599,10 +599,13 @@ int printf_frames(uint8_t* bits, int max_frames,
} }
return i; 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++) { for (i = 0; i < FRAME_SIZE*8; i++) {
if (!frame_get_bit(bits, i)) continue; if (!frame_get_bit(bits, i)) continue;
if (i >= 512 && i < 528) { // hclk if (i >= 512 && i < 528) { // hclk
if (!no_clock)
printf("%sbit %i\n", prefix, i); printf("%sbit %i\n", prefix, i);
continue; continue;
} }
@ -623,7 +626,7 @@ int printf_frames(uint8_t* bits, int max_frames,
return 1; 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; int i;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
@ -649,7 +652,7 @@ int clb_empty(uint8_t* maj_bits, int idx)
return 1; 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 start_bit, int num_bits, int row, int major)
{ {
int minor, bit; 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; uint64_t lut64 = 0;
int j; int j;
for (j = 0; j < 16; 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); 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); 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); 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); lut64 |= 1LL << (j*4+3);
} }
return lut64; 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); int printf_iob(uint8_t* d, int len, int inpos, int num_entries);
void printf_ramb16_data(uint8_t* bits, int inpos); 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);
int count_bits(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_clear_bit(uint8_t* frame_d, int bit);
void frame_set_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); uint8_t frame_get_u8(const uint8_t* frame_d);
uint16_t frame_get_u16(uint8_t* frame_d); uint16_t frame_get_u16(const uint8_t* frame_d);
uint32_t frame_get_u32(uint8_t* frame_d); uint32_t frame_get_u32(const uint8_t* frame_d);
uint64_t frame_get_u64(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_u8(uint8_t* frame_d, uint8_t v);
void frame_set_u16(uint8_t* frame_d, uint16_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 // if row is negative, it's an absolute frame number and major and
// minor are ignored // minor are ignored
int printf_frames(uint8_t* bits, int max_frames, int row, int major, int printf_frames(const uint8_t* bits, int max_frames, int row, int major,
int minor, int print_empty); int minor, int print_empty, int no_clock);
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 clb_empty(uint8_t* maj_bits, int idx); 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); 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); void write_lut64(uint8_t* two_minors, int off_in_frame, uint64_t u64);
int get_vm_mb(void); 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 { FF_SRINIT0 = 1, FF_SRINIT1 };
enum { MUX_O6 = 1, MUX_O5, MUX_5Q, MUX_X, MUX_F7, MUX_CY, MUX_XOR }; 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 { FF_OR2L = 1, FF_AND2L, FF_LATCH, FF_FF };
enum { CY0_X = 1, CY0_O5 };
enum { CLKINV_B = 1, CLKINV_CLK }; enum { CLKINV_B = 1, CLKINV_CLK };
enum { SYNCATTR_SYNC = 1, SYNCATTR_ASYNC }; enum { SYNCATTR_SYNC = 1, SYNCATTR_ASYNC };
enum { WEMUX_WE = 1, WEMUX_CE }; enum { WEMUX_WE = 1, WEMUX_CE };
enum { PRECYINIT_0 = 1, PRECYINIT_1, PRECYINIT_AX };
#define MAX_LUT_LEN 2048 #define MAX_LUT_LEN 2048
@ -427,6 +429,7 @@ struct fpgadev_logic_a2d
int ff_srinit; // SRINIT0, SRINIT1 int ff_srinit; // SRINIT0, SRINIT1
int out_mux; // O6, O5, 5Q, F7, CY, XOR int out_mux; // O6, O5, 5Q, F7, CY, XOR
int ff; // OR2L, AND2L, LATCH, FF int ff; // OR2L, AND2L, LATCH, FF
int cy0; // X, O5
}; };
struct fpgadev_logic struct fpgadev_logic
@ -437,6 +440,8 @@ struct fpgadev_logic
int ce_used; int ce_used;
int sr_used; int sr_used;
int we_mux; // WEMUX_WE, WEMUX_CE 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; 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 // routing switches
// //

View File

@ -81,6 +81,8 @@ enum major_type get_major_type(int idcode, int major);
#define XC6_SLX9_RIGHTMOST_MAJOR 17 #define XC6_SLX9_RIGHTMOST_MAJOR 17
int get_rightside_major(int idcode); 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); int get_num_iobs(int idcode);
const char* get_iob_sitename(int idcode, int idx); const char* get_iob_sitename(int idcode, int idx);