preparing for some more lut work
This commit is contained in:
parent
1a1b861956
commit
fd21f8ce9d
6
Makefile
6
Makefile
|
@ -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
8
README
|
@ -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
|
||||
|
|
316
libs/bit_regs.c
316
libs/bit_regs.c
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
//
|
||||
|
|
15
libs/parts.c
15
libs/parts.c
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user