diff --git a/autotest.c b/autotest.c index a5305f2..a00e503 100644 --- a/autotest.c +++ b/autotest.c @@ -33,6 +33,7 @@ static int dump_file(const char* path) char line[1024]; FILE* f; + printf("\n"); printf("O begin dump %s\n", path); f = fopen(path, "r"); EXIT(!f); @@ -45,6 +46,7 @@ static int dump_file(const char* path) } fclose(f); printf("O end dump %s\n", path); + printf("\n"); return 0; } @@ -157,17 +159,15 @@ int main(int argc, char** argv) P48_dev->iob.suspend = SUSP_3STATE; // configure logic - logic_dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, /*LOGIC_X*/ 1); + logic_dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX); if (!logic_dev) FAIL(EINVAL); logic_dev->instantiated = 1; logic_dev->logic.D_used = 1; rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM); if (rc) FAIL(rc); -#if 1 rc = diff_printf(&tstate); if (rc) goto fail; -#endif printf("P46 I pinw %s\n", P46_dev->iob.pinw_out_I); for (i = 0;; i++) { diff --git a/autotest_diff.sh b/autotest_diff.sh index 7bc9c27..e65d784 100755 --- a/autotest_diff.sh +++ b/autotest_diff.sh @@ -2,7 +2,7 @@ diff -U 0 $1 $2 > ${2%.*}.fp_diff ./fp2bit $2 ${2%.*}.f2b || exit $? -./bit2fp --bits-only ${2%.*}.f2b > ${2%.*}.b2f || exit $? +./bit2fp --no-fp-header ${2%.*}.f2b > ${2%.*}.b2f || exit $? if [ "$1" == "/dev/null" ] then diff -U 0 /dev/null ${2%.*}.b2f > ${2%.*}.b2f_diff @@ -10,5 +10,7 @@ else diff -U 0 ${1%.*}.b2f ${2%.*}.b2f > ${2%.*}.b2f_diff fi -cat ${2%.*}.fp_diff | sed -e '/^--- /d;/^+++ /d;/^@@ /d' > ${2%.*}.diff +echo "fp:" > ${2%.*}.diff +cat ${2%.*}.fp_diff | sed -e '/^--- /d;/^+++ /d;/^@@ /d' >> ${2%.*}.diff +echo "b2f:" >> ${2%.*}.diff cat ${2%.*}.b2f_diff | sed -e '/^--- /d;/^+++ /d;/^@@ /d' >> ${2%.*}.diff diff --git a/bit.h b/bit.h index 212286a..4f5620f 100644 --- a/bit.h +++ b/bit.h @@ -57,20 +57,6 @@ enum { CMD_DESYNC = 13, CMD_IPROG }; -#define FRAME_SIZE 130 -#define FRAMES_PER_ROW 505 // for slx4 and slx9 -#define PADDING_FRAMES_PER_ROW 2 -#define NUM_ROWS 4 // for slx9 and slx9 - -#define FRAMES_DATA_START 0 -#define FRAMES_DATA_LEN (NUM_ROWS*FRAMES_PER_ROW*FRAME_SIZE) -#define BRAM_DATA_START FRAMES_DATA_LEN -#define BRAM_DATA_LEN (4*144*FRAME_SIZE) -#define IOB_DATA_START (BRAM_DATA_START + BRAM_DATA_LEN) -#define IOB_WORDS 896 // 16-bit words, for slx4 and slx9 -#define IOB_DATA_LEN (IOB_WORDS*2) -#define BITS_LEN (IOB_DATA_START+IOB_DATA_LEN) - #define MAX_HEADER_STR_LEN 128 #define MAX_REG_ACTIONS 256 diff --git a/bit2fp.c b/bit2fp.c index 493afd3..9bb1ac7 100644 --- a/bit2fp.c +++ b/bit2fp.c @@ -12,7 +12,7 @@ int main(int argc, char** argv) { struct fpga_model model; - int bit_header, bit_regs, fp_header, file_arg, flags, rc = -1; + int bit_header, bit_regs, fp_header, pull_model, file_arg, flags, rc = -1; struct fpga_config config; // parameters @@ -20,12 +20,13 @@ int main(int argc, char** argv) fprintf(stderr, "\n" "%s - bitstream to floorplan\n" - "Usage: %s [--bit-header] [--bit-regs] [--no-fp-header] \n" + "Usage: %s [--bit-header] [--bit-regs] [--no-model] [--no-fp-header] \n" "\n", argv[0], argv[0]); goto fail; } bit_header = 0; bit_regs = 0; + pull_model = 1; fp_header = 1; file_arg = 1; while (!strncmp(argv[file_arg], "--", 2)) { @@ -33,6 +34,8 @@ int main(int argc, char** argv) bit_header = 1; else if (!strcmp(argv[file_arg], "--bit-regs")) bit_regs = 1; + else if (!strcmp(argv[file_arg], "--no-model")) + pull_model = 0; else if (!strcmp(argv[file_arg], "--no-fp-header")) fp_header = 0; else break; @@ -54,7 +57,8 @@ int main(int argc, char** argv) // build model and fill from bitstream if ((rc = fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS, XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING))) FAIL(rc); - if ((rc = extract_model(&model, &config.bits))) FAIL(rc); + if (pull_model) + if ((rc = extract_model(&model, &config.bits))) FAIL(rc); // dump model flags = FP_DEFAULT; diff --git a/bit_frames.c b/bit_frames.c index b3e57c9..88c7f71 100644 --- a/bit_frames.c +++ b/bit_frames.c @@ -8,6 +8,9 @@ #include "model.h" #include "bit.h" #include "parts.h" +#include "control.h" + +#define HCLK_BYTES 2 static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major) { @@ -22,21 +25,21 @@ static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major) static int get_bit(struct fpga_bits* bits, int row, int major, int minor, int bit_i) { - return get_framebit(get_first_minor(bits, row, major) + return frame_get_bit(get_first_minor(bits, row, major) + minor*FRAME_SIZE, bit_i); } static void set_bit(struct fpga_bits* bits, int row, int major, int minor, int bit_i) { - return set_framebit(get_first_minor(bits, row, major) + return frame_set_bit(get_first_minor(bits, row, major) + minor*FRAME_SIZE, bit_i); } static void clear_bit(struct fpga_bits* bits, int row, int major, int minor, int bit_i) { - return clear_framebit(get_first_minor(bits, row, major) + return frame_clear_bit(get_first_minor(bits, row, major) + minor*FRAME_SIZE, bit_i); } @@ -72,13 +75,147 @@ static struct bit_pos s_default_bits[] = { int extract_model(struct fpga_model* model, struct fpga_bits* bits) { - int i, rc; + int i, num_iobs, iob_y, iob_x, iob_idx, row, row_pos, rc; + int x, y, byte_off; + uint32_t* u32_p; + uint8_t* u8_p; + uint64_t u64; + const char* iob_sitename, *lut_str; + struct fpga_device* dev; for (i = 0; i < sizeof(s_default_bits)/sizeof(s_default_bits[0]); i++) { if (!get_bitp(bits, &s_default_bits[i])) FAIL(EINVAL); clear_bitp(bits, &s_default_bits[i]); } + + // IOBs + num_iobs = get_num_iobs(XC6SLX9); + for (i = 0; i < num_iobs; i++) { + u32_p = (uint32_t*) &bits->d[IOB_DATA_START + i*IOB_ENTRY_LEN]; + if (!u32_p[0] && !u32_p[1]) + continue; + iob_sitename = get_iob_sitename(XC6SLX9, i); + if (!iob_sitename) { + HERE(); + continue; + } + rc = fpga_find_iob(model, iob_sitename, &iob_y, &iob_x, &iob_idx); + if (rc) FAIL(rc); + dev = fpga_dev(model, iob_y, iob_x, DEV_IOB, iob_idx); + if (!dev) FAIL(rc); + + // we only support 2 hardcoded types of IOB right now + if (u32_p[0] == 0x00000100 + && u32_p[1] == 0x06001100) { + dev->instantiated = 1; + strcpy(dev->iob.ostandard, IO_LVCMOS33); + dev->iob.drive_strength = 12; + dev->iob.O_used = 1; + dev->iob.slew = SLEW_SLOW; + dev->iob.suspend = SUSP_3STATE; + u32_p[0] = 0; + u32_p[1] = 0; + } else if (u32_p[0] == 0x00000107 + && u32_p[1] == 0x0B002400) { + dev->instantiated = 1; + strcpy(dev->iob.istandard, IO_LVCMOS33); + dev->iob.bypass_mux = BYPASS_MUX_I; + dev->iob.I_mux = IMUX_I; + u32_p[0] = 0; + u32_p[1] = 0; + } else HERE(); + } + + // logic + for (x = LEFT_SIDE_WIDTH; x < model->x_width-RIGHT_SIDE_WIDTH; x++) { + if (!is_atx(X_LOGIC_COL, model, x)) + continue; + for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) { + if (!has_device_type(model, y, x, DEV_LOGIC, LOGIC_M)) + continue; + row = which_row(y, model); + row_pos = pos_in_row(y, model); + if (row == -1 || row_pos == -1 || row_pos == 8) { + HERE(); + continue; + } + if (row_pos > 8) row_pos--; + u8_p = get_first_minor(bits, row, model->x_major[x]); + byte_off = row_pos * 8; + if (row_pos >= 8) byte_off += HCLK_BYTES; + + u64 = frame_get_u64(u8_p + 26*FRAME_SIZE + byte_off); + if ( u64 ) { + // 21, 22, 36 and 37 are actually not default + // and can go off with the FFMUXes or routing + // say D over the FF to DQ etc. (AFFMUX=b37, + // BFFMUX=b36, CFFMUX=b22, DFFMUX=b21). + if (!(u64 & (1ULL<<1) && u64 & (1ULL<<2) + && u64 & (1ULL<<7) && u64 & (1ULL<<21) + && u64 & (1ULL<<22) && u64 & (1ULL<<36) + && u64 & (1ULL<<37) && u64 & (1ULL<<39))) + continue; + if (u64 & ~(0x000000B000600086ULL)) + continue; + + // any logic block will enable r0ma17mi22b980 + if (!get_bit(bits, /*row*/ 0, /*major*/ 17, + /*minor*/ 22, /*bit_i*/ 980)) { + HERE(); + continue; + } + clear_bit(bits, /*row*/ 0, /*major*/ 17, + /*minor*/ 22, /*bit_i*/ 980); + + dev = fpga_dev(model, y, x, DEV_LOGIC, DEV_LOGX); + if (!dev) FAIL(EINVAL); + dev->instantiated = 1; + *(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0; + + u64 = read_lut64(u8_p + 27*FRAME_SIZE, (byte_off+4)*8); + { int logic_base[6] = {1,1,0,1,1,0}; + lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); } + if (*lut_str) { + rc = fpga_set_lut(model, dev, A6_LUT, lut_str, ZTERM); + if (rc) FAIL(rc); + dev->logic.A_used = 1; + *(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off+4) = 0; + *(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off+4) = 0; + } + u64 = read_lut64(u8_p + 29*FRAME_SIZE, (byte_off+4)*8); + { int logic_base[6] = {1,1,0,1,1,0}; + lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); } + if (*lut_str) { + rc = fpga_set_lut(model, dev, B6_LUT, lut_str, ZTERM); + if (rc) FAIL(rc); + dev->logic.B_used = 1; + *(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off+4) = 0; + *(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off+4) = 0; + } + u64 = read_lut64(u8_p + 27*FRAME_SIZE, byte_off*8); + { int logic_base[6] = {0,1,0,0,0,1}; + lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); } + if (*lut_str) { + rc = fpga_set_lut(model, dev, C6_LUT, lut_str, ZTERM); + if (rc) FAIL(rc); + dev->logic.C_used = 1; + *(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off) = 0; + *(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off) = 0; + } + u64 = read_lut64(u8_p + 29*FRAME_SIZE, byte_off*8); + { int logic_base[6] = {0,1,0,0,0,1}; + lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); } + if (*lut_str) { + rc = fpga_set_lut(model, dev, D6_LUT, lut_str, ZTERM); + if (rc) FAIL(rc); + dev->logic.D_used = 1; + *(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0; + *(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0; + } + } + } + } return 0; fail: return rc; diff --git a/bit_regs.c b/bit_regs.c index c1d34c4..a519125 100644 --- a/bit_regs.c +++ b/bit_regs.c @@ -797,17 +797,17 @@ static void printf_clb(uint8_t* maj_bits, int row, int major) // bits for (j = 0; j < 64; j++) { - if (get_framebit(&maj_bits[20*130], frame_off + j)) + if (frame_get_bit(&maj_bits[20*130], frame_off + j)) printf("r%i ma%i clb i%i mi20 bit %i\n", row, major, i-start, j); } for (j = 0; j < 64; j++) { - if (get_framebit(&maj_bits[23*130], frame_off + j)) + if (frame_get_bit(&maj_bits[23*130], frame_off + j)) printf("r%i ma%i clb i%i mi23 bit %i\n", row, major, i-start, j); } for (j = 0; j < 64; j++) { - if (get_framebit(&maj_bits[26*130], frame_off + j)) + if (frame_get_bit(&maj_bits[26*130], frame_off + j)) printf("r%i ma%i clb i%i mi26 bit %i\n", row, major, i-start, j); } @@ -822,7 +822,8 @@ static int dump_bits(struct fpga_config* cfg) off = 0; for (row = 0; row < 4; row++) { for (major = 0; major < 18; major++) { - if (major == 7) { // MACC + // todo: the macc/bram/logic special cases can be removed + if (0 && major == 7) { // MACC int last_extra_minor; if (!row || row == 3) @@ -845,14 +846,13 @@ static int dump_bits(struct fpga_config* cfg) for (minor = last_extra_minor+1; minor < 24; minor++) { for (j = 0; j < 256; j++) { - if (get_framebit(&cfg->bits.d[off+minor*130], i*256 + ((i>=2)?16:0) + 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 (major == 2 || major == 3 || major == 5 || major == 6 - || major == 8 || major == 10 || major == 11 || major == 12 - || major == 13 || major == 15 || major == 16) { // logic + } else if (0 && (major == 2 || major == 5 || major == 8 || major == 10 + || major == 12 || major == 15)) { // logic_m minor = 0; while (minor < 20) { minor += printf_frames(&cfg->bits.d[off @@ -874,7 +874,7 @@ static int dump_bits(struct fpga_config* cfg) // clbs printf_clb(&cfg->bits.d[off], row, major); - } else if (major == 4 || major == 14) { // bram + } else if (0 && (major == 4 || major == 14)) { // bram ramb16_cfg_t ramb16_cfg[4]; // minors 0..22 @@ -918,7 +918,7 @@ static int dump_bits(struct fpga_config* cfg) row, major, minor, /*print_empty*/ 0); } } - off += get_major_minors(XC6SLX9, major) * 130; + off += get_major_minors(XC6SLX9, major) * FRAME_SIZE; } } return 0; diff --git a/control.c b/control.c index 1ebde85..c0c115f 100644 --- a/control.c +++ b/control.c @@ -31,17 +31,17 @@ static const struct iob_site xc6slx9_iob_top[] = static const struct iob_site xc6slx9_iob_bottom[] = { - { 5, {"P39", "P38", "P40", "P41"}}, - { 7, {"UNB139", "UNB140", "P43", "P44"}}, - {12, {"P46", "P45", "P47", "P48"}}, - {14, {"UNB131", "UNB132", "UNB130", "UNB129"}}, - {19, {"UNB127", "UNB128", "UNB126", "UNB125"}}, - {21, {"UNB123", "UNB124", "P50", "P51"}}, - {25, {"P56", "P55", "UNB118", "UNB117"}}, - {29, {"UNB115", "UNB116", "UNB114", "UNB113"}}, - {31, {"P58", "P57", "P59", "P60"}}, - {36, {"P62", "P61", "P64", "P65"}}, - {38, {"P67", "P66", "P69", "P70"}}, + { 5, {"P38", "P39", "P40", "P41"}}, + { 7, {"UNB140", "UNB139", "P43", "P44"}}, + {12, {"P45", "P46", "P47", "P48"}}, + {14, {"UNB132", "UNB131", "UNB130", "UNB129"}}, + {19, {"UNB128", "UNB127", "UNB126", "UNB125"}}, + {21, {"UNB124", "UNB123", "P50", "P51"}}, + {25, {"P55", "P56", "UNB118", "UNB117"}}, + {29, {"UNB116", "UNB115", "UNB114", "UNB113"}}, + {31, {"P57", "P58", "P59", "P60"}}, + {36, {"P61", "P62", "P64", "P65"}}, + {38, {"P66", "P67", "P69", "P70"}}, }; static const struct iob_site xc6slx9_iob_left[] = diff --git a/helper.c b/helper.c index f257a80..d11304c 100644 --- a/helper.c +++ b/helper.c @@ -6,6 +6,7 @@ // #include "helper.h" +#include "parts.h" const char* bitstr(uint32_t value, int digits) { @@ -480,34 +481,67 @@ int count_bits(uint8_t* d, int l) return bits; } -int get_framebit(uint8_t* frame_d, int bit) +int frame_get_bit(uint8_t* frame_d, int bit) { uint8_t v = 1<<(7-(bit%8)); return (frame_d[(bit/16)*2 + !((bit/8)%2)] & v) != 0; } -void clear_framebit(uint8_t* frame_d, int bit) +void frame_clear_bit(uint8_t* frame_d, int bit) { uint8_t v = 1<<(7-(bit%8)); frame_d[(bit/16)*2 + !((bit/8)%2)] &= ~v; } -void set_framebit(uint8_t* frame_d, int bit) +void frame_set_bit(uint8_t* frame_d, int bit) { uint8_t v = 1<<(7-(bit%8)); frame_d[(bit/16)*2 + !((bit/8)%2)] |= v; } +uint8_t frame_get_u8(uint8_t* frame_d) +{ + uint8_t v = 0; + int i; + for (i = 0; i < 8; i++) + if (*frame_d & (1<= 512) ? i + 16 : i)) + 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); + continue; + } + i_without_clk = i; + if (i_without_clk >= 528) + i_without_clk -= 16; + snprintf(suffix, sizeof(suffix), "64*%i+%i 256*%i+%i", + i_without_clk/64, i_without_clk%64, + i_without_clk/256, i_without_clk%256); + printf("%sbit %i %s\n", prefix, i, suffix); } return 1; } @@ -541,7 +584,7 @@ void printf_clock(uint8_t* frame, int row, int major, int minor) { int i; for (i = 0; i < 16; i++) { - if (get_framebit(frame, 512 + i)) + if (frame_get_bit(frame, 512 + i)) printf("r%i ma%i mi%i clock %i\n", row, major, minor, i); } @@ -570,7 +613,7 @@ void printf_extrabits(uint8_t* maj_bits, int start_minor, int num_minors, for (minor = start_minor; minor < start_minor + num_minors; minor++) { for (bit = start_bit; bit < start_bit + num_bits; bit++) { - if (get_framebit(&maj_bits[minor*130], bit)) + if (frame_get_bit(&maj_bits[minor*130], bit)) printf("r%i ma%i extra mi%i bit %i\n", row, major, minor, bit); } @@ -583,13 +626,13 @@ uint64_t read_lut64(uint8_t* two_minors, int off_in_frame) int j; for (j = 0; j < 16; j++) { - if (get_framebit(two_minors, off_in_frame+j*2)) + if (frame_get_bit(two_minors, off_in_frame+j*2)) lut64 |= 1LL << (j*4); - if (get_framebit(two_minors, off_in_frame+(j*2)+1)) + if (frame_get_bit(two_minors, off_in_frame+(j*2)+1)) lut64 |= 1LL << (j*4+1); - if (get_framebit(&two_minors[130], off_in_frame+j*2)) + if (frame_get_bit(&two_minors[130], off_in_frame+j*2)) lut64 |= 1LL << (j*4+2); - if (get_framebit(&two_minors[130], off_in_frame+(j*2)+1)) + if (frame_get_bit(&two_minors[130], off_in_frame+(j*2)+1)) lut64 |= 1LL << (j*4+3); } return lut64; diff --git a/helper.h b/helper.h index c565149..e440903 100644 --- a/helper.h +++ b/helper.h @@ -64,9 +64,15 @@ 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 get_framebit(uint8_t* frame_d, int bit); -void clear_framebit(uint8_t* frame_d, int bit); -void set_framebit(uint8_t* frame_d, int bit); + +int frame_get_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); + +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); // if row is negative, it's an absolute frame number and major and // minor are ignored diff --git a/model.h b/model.h index c745979..2e62f9b 100644 --- a/model.h +++ b/model.h @@ -50,6 +50,8 @@ /* row 1 */ "WWWUUWUU" "WUUWUUWU" \ /* row 0 */ "UWUUWUUW" "UUWWWWUU" +#define LEFT_SIDE_MAJOR 1 + struct fpga_model { int cfg_rows; @@ -64,6 +66,12 @@ struct fpga_model // column as indicated in the chip's cfg_columns with a 'g'. int left_gclk_sep_x, right_gclk_sep_x; + // x_major is an array of column indices for each x coordinate, + // starting with column 1 for the left side, and incrementing + // through the configuration columns. This corresponds to the + // 'majors' in the bitstream. + int x_major[512]; + struct fpga_tile* tiles; struct hashed_strarray str; @@ -304,6 +312,12 @@ enum fpgadev_type DEV_SPI_ACCESS }; +// M and L device is always at type index 0, X device +// is always at type index 1. +#define DEV_LOGM 0 +#define DEV_LOGL 0 +#define DEV_LOGX 1 + // All device configuration is structured so that the value // 0 is never a valid configured setting. That way all config // data can safely be initialized to 0 meaning unconfigured. diff --git a/model_devices.c b/model_devices.c index 85b7f6a..52a3845 100644 --- a/model_devices.c +++ b/model_devices.c @@ -346,8 +346,8 @@ int init_devices(struct fpga_model* model) if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail; y = model->y_height-BOT_OUTER_ROW; - if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail; if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail; + if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail; if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail; if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail; } @@ -413,7 +413,7 @@ int init_devices(struct fpga_model* model) if (!is_atx(X_LOGIC_COL, model, x)) continue; for (y = TOP_IO_TILES; y < model->y_height - BOT_IO_TILES; y++) { - // M and L are at index 0, X is at index 1. + // M and L are at index 0 (DEV_LOGM and DEV_LOGL), X is at index 1 (DEV_LOGX). if (YX_TILE(model, y, x)->flags & TF_LOGIC_XM_DEV) { if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_M))) goto fail; if ((rc = add_dev(model, y, x, DEV_LOGIC, LOGIC_X))) goto fail; diff --git a/model_tiles.c b/model_tiles.c index 99dd225..f46c434 100644 --- a/model_tiles.c +++ b/model_tiles.c @@ -11,7 +11,7 @@ int init_tiles(struct fpga_model* model) { int tile_rows, tile_columns, i, j, k, l, row_top_y, left_side; - int start, end, no_io; + int start, end, no_io, cur_major; char cur_cfgcol, last_col; struct fpga_tile* tile_i0; @@ -50,7 +50,10 @@ int init_tiles(struct fpga_model* model) // left_side = 1; // turn off (=right side) when reaching the 'R' middle column - i = 5; // skip left IO columns + for (i = 0; i < LEFT_SIDE_WIDTH; i++) + model->x_major[i] = LEFT_SIDE_MAJOR; + cur_major = LEFT_SIDE_MAJOR+1; + // i is now LEFT_SIDE_WIDTH (5) for (j = 0; model->cfg_columns[j]; j++) { cur_cfgcol = model->cfg_columns[j]; switch (cur_cfgcol) { @@ -139,8 +142,12 @@ int init_tiles(struct fpga_model* model) model->tiles[model->center_y*tile_columns + i].type = REGH_ROUTING_XM; model->tiles[model->center_y*tile_columns + i + 1].type = REGH_LOGIC_XM; } - i += 2; + + for (k = 0; k < 2; k++) + model->x_major[i++] = cur_major; + cur_major++; break; + case 'B': if (next_non_whitespace(&model->cfg_columns[j+1]) == 'g') { if (left_side) @@ -182,8 +189,12 @@ int init_tiles(struct fpga_model* model) model->tiles[model->center_y*tile_columns + i].type = REGH_BRAM_ROUTING; model->tiles[model->center_y*tile_columns + i + 1].type = REGH_BRAM_ROUTING_VIA; model->tiles[model->center_y*tile_columns + i + 2].type = left_side ? REGH_BRAM_L : REGH_BRAM_R; - i += 3; + + for (k = 0; k < 3; k++) + model->x_major[i++] = cur_major; + cur_major++; break; + case 'D': model->tiles[i].flags |= TF_FABRIC_ROUTING_COL; model->tiles[i].flags |= TF_ROUTING_NO_IO; // no_io always on for MACC @@ -219,8 +230,12 @@ int init_tiles(struct fpga_model* model) model->tiles[model->center_y*tile_columns + i].type = REGH_MACC_ROUTING; model->tiles[model->center_y*tile_columns + i + 1].type = REGH_MACC_ROUTING_VIA; model->tiles[model->center_y*tile_columns + i + 2].type = REGH_MACC_L; - i += 3; + + for (k = 0; k < 3; k++) + model->x_major[i++] = cur_major; + cur_major++; break; + case 'R': if (next_non_whitespace(&model->cfg_columns[j+1]) != 'M') { // We expect a LOGIC_XM column to follow the center for @@ -320,17 +335,22 @@ int init_tiles(struct fpga_model* model) model->tiles[model->center_y*tile_columns + i + 2].type = REGC_CMT; model->tiles[model->center_y*tile_columns + i + 3].type = CENTER; - i += 4; + for (k = 0; k < 4; k++) + model->x_major[i++] = cur_major; + cur_major++; break; case ' ': // space used to make string more readable only case 'g': // global clock separator case 'n': // noio for logic blocks break; default: - fprintf(stderr, "Ignoring unexpected column identifier '%c'\n", cur_cfgcol); + fprintf(stderr, "Ignoring unexpected column " + "identifier '%c'\n", cur_cfgcol); break; } } + for (k = 0; k < RIGHT_SIDE_WIDTH; k++) + model->x_major[i++] = cur_major; // // left IO diff --git a/parts.c b/parts.c index 2f80935..6e1c924 100644 --- a/parts.c +++ b/parts.c @@ -8,7 +8,7 @@ #include "helper.h" #include "parts.h" -const char* iob_xc6slx4_sitenames[896*2/8] = +const char* iob_xc6slx9_sitenames[IOB_WORDS*2/8] = { [0x0000/8] "P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61", @@ -54,6 +54,22 @@ const char* iob_xc6slx4_sitenames[896*2/8] = 0, 0, 0, 0, 0, 0, "P75", "P74" }; +int get_num_iobs(int idcode) +{ + if ((idcode & IDCODE_MASK) != XC6SLX9) + EXIT(1); + return sizeof(iob_xc6slx9_sitenames)/sizeof(iob_xc6slx9_sitenames[0]); +} + +const char* get_iob_sitename(int idcode, int idx) +{ + if ((idcode & IDCODE_MASK) != XC6SLX9) + EXIT(1); + if (idx < 0 || idx > sizeof(iob_xc6slx9_sitenames)/sizeof(iob_xc6slx9_sitenames[0])) + EXIT(1); + return iob_xc6slx9_sitenames[idx]; +} + static const int minors_per_major[] = // for slx4 and slx9 { /* 0 */ 4, // 505 bytes = middle 8-bit for each minor? diff --git a/parts.h b/parts.h index 6cd20b7..c890162 100644 --- a/parts.h +++ b/parts.h @@ -23,4 +23,21 @@ #define XC6SLX100T 0x04031093 #define XC6SLX150 0x0401D093 +#define FRAME_SIZE 130 +#define FRAMES_PER_ROW 505 // for slx4 and slx9 +#define PADDING_FRAMES_PER_ROW 2 +#define NUM_ROWS 4 // for slx9 and slx9 + +#define FRAMES_DATA_START 0 +#define FRAMES_DATA_LEN (NUM_ROWS*FRAMES_PER_ROW*FRAME_SIZE) +#define BRAM_DATA_START FRAMES_DATA_LEN +#define BRAM_DATA_LEN (4*144*FRAME_SIZE) +#define IOB_DATA_START (BRAM_DATA_START + BRAM_DATA_LEN) +#define IOB_WORDS 896 // 16-bit words, for slx4 and slx9 +#define IOB_DATA_LEN (IOB_WORDS*2) +#define IOB_ENTRY_LEN 8 +#define BITS_LEN (IOB_DATA_START+IOB_DATA_LEN) + int get_major_minors(int idcode, int major); +int get_num_iobs(int idcode); +const char* get_iob_sitename(int idcode, int idx);