From fd21f8ce9dba9e48c427b65ec1ea100ac0a3b9f0 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Mon, 1 Oct 2012 04:09:52 +0200 Subject: [PATCH] preparing for some more lut work --- Makefile | 6 +- README | 8 +- libs/bit_regs.c | 374 ++++++++++++++++++++++++++++++++++------------- libs/floorplan.c | 62 +++++++- libs/helper.c | 39 ++--- libs/helper.h | 24 +-- libs/model.h | 5 + libs/parts.c | 15 ++ libs/parts.h | 2 + 9 files changed, 388 insertions(+), 147 deletions(-) diff --git a/Makefile b/Makefile index ebcfc7b..01372c0 100644 --- a/Makefile +++ b/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 diff --git a/README b/README index 9c6ad0b..68cd798 100644 --- a/README +++ b/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 diff --git a/libs/bit_regs.c b/libs/bit_regs.c index 92b88c0..5c20470 100644 --- a/libs/bit_regs.c +++ b/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,115 +761,283 @@ static void printf_v64_mi20(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]; + + 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); + + 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); + } +} + +static int dump_maj_zero(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_left(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_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(&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_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 + 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] = 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++) { + for (j = 0; j < 64; j++) { + if (ramb16_cfg[i].byte[j]) + break; + } + if (j >= 64) + continue; + printf("r%i ma%i ramb16 i%i\n", + row, major, i); + print_ramb16_cfg(&ramb16_cfg[i]); + } + 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, minor, i, j, off, offset_in_frame; + int row, major, off, rc; // 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; - - 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); - } - - // clock - for (; minor < 24; minor++) - printf_clock(&cfg->bits.d[off+minor*130], - row, major, 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); - - // bitwise - minor = 0; - while (minor < 31) { - minor += printf_frames(&cfg->bits.d[off - +minor*130], 31 - minor, - row, major, minor, /*print_empty*/ 0); - } - - // 0:20 routing minor pairs - for (i = 0; i < 10; i++) - printf_routing_2minors(&cfg->bits.d[ - off+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]; - - // 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); - } - - // 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]; - } - } - for (i = 0; i < 4; i++) { - for (j = 0; j < 64; j++) { - if (ramb16_cfg[i].byte[j]) - break; - } - if (j >= 64) - continue; - printf("r%i ma%i ramb16 i%i\n", - 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); - } + 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) diff --git a/libs/floorplan.c b/libs/floorplan.c index ba3b8e8..7a62adc 100644 --- a/libs/floorplan.c +++ b/libs/floorplan.c @@ -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; diff --git a/libs/helper.c b/libs/helper.c index 245bcc4..ab2c6a0 100644 --- a/libs/helper.c +++ b/libs/helper.c @@ -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,11 +599,14 @@ 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 - printf("%sbit %i\n", prefix, i); + if (!no_clock) + printf("%sbit %i\n", prefix, i); continue; } i_without_clk = i; @@ -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; diff --git a/libs/helper.h b/libs/helper.h index 564b8ed..99a16fe 100644 --- a/libs/helper.h +++ b/libs/helper.h @@ -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); diff --git a/libs/model.h b/libs/model.h index 5e0c3b8..6b4c51e 100644 --- a/libs/model.h +++ b/libs/model.h @@ -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 }; // diff --git a/libs/parts.c b/libs/parts.c index 0f3e6a7..6fffb12 100644 --- a/libs/parts.c +++ b/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 // diff --git a/libs/parts.h b/libs/parts.h index 23159e0..3d6a854 100644 --- a/libs/parts.h +++ b/libs/parts.h @@ -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);