diff --git a/libs/bit_frames.c b/libs/bit_frames.c index 58213cc..2016e89 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -553,155 +553,54 @@ fail: return rc; } -#if 0 - // M device - dev_idx = fpga_dev_idx(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L); - if (dev_idx == NO_DEV) FAIL(EINVAL); +static int lut2str(uint64_t lut, int lut_pos, int lut5_used, + char *lut6_buf, char** lut6_p, char *lut5_buf, char** lut5_p) +{ + int lut_map[64], rc; + uint64_t lut_mapped; + const char* str; - // A6_LUT - if (frame_get_u32(u8_p + 24*FRAME_SIZE + byte_off + 4) - || frame_get_u32(u8_p + 25*FRAME_SIZE + byte_off + 4)) { - u64 = read_lut64(u8_p + 24*FRAME_SIZE, (byte_off+4)*8); - { int logic_base[6] = {0,1,0,0,1,0}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); } - if (*lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L, - LUT_A, 6, lut_str, ZTERM); - if (rc) FAIL(rc); - *(uint32_t*)(u8_p+24*FRAME_SIZE+byte_off+4) = 0; - *(uint32_t*)(u8_p+25*FRAME_SIZE+byte_off+4) = 0; - } - } - // B6_LUT - if (frame_get_u32(u8_p + 21*FRAME_SIZE + byte_off + 4) - || frame_get_u32(u8_p + 22*FRAME_SIZE + byte_off + 4)) { - u64 = read_lut64(u8_p + 21*FRAME_SIZE, (byte_off+4)*8); - { int logic_base[6] = {1,1,0,1,0,1}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); } - if (*lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L, - LUT_B, 6, lut_str, ZTERM); - if (rc) FAIL(rc); - *(uint32_t*)(u8_p+21*FRAME_SIZE+byte_off+4) = 0; - *(uint32_t*)(u8_p+22*FRAME_SIZE+byte_off+4) = 0; - } - } - // C6_LUT - if (frame_get_u32(u8_p + 24*FRAME_SIZE + byte_off) - || frame_get_u32(u8_p + 25*FRAME_SIZE + byte_off)) { - u64 = read_lut64(u8_p + 24*FRAME_SIZE, byte_off*8); - { int logic_base[6] = {0,1,0,0,1,0}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); } - if (*lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L, - LUT_C, 6, lut_str, ZTERM); - if (rc) FAIL(rc); - *(uint32_t*)(u8_p+24*FRAME_SIZE+byte_off) = 0; - *(uint32_t*)(u8_p+25*FRAME_SIZE+byte_off) = 0; - } - } - // D6_LUT - if (frame_get_u32(u8_p + 21*FRAME_SIZE + byte_off) - || frame_get_u32(u8_p + 22*FRAME_SIZE + byte_off)) { - u64 = read_lut64(u8_p + 21*FRAME_SIZE, byte_off*8); - { int logic_base[6] = {1,1,0,1,0,1}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 1); } - if (*lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_M_OR_L, - LUT_D, 6, lut_str, ZTERM); - if (rc) FAIL(rc); - *(uint32_t*)(u8_p+21*FRAME_SIZE+byte_off) = 0; - *(uint32_t*)(u8_p+22*FRAME_SIZE+byte_off) = 0; - } - } + if (lut5_used) { + xc6_lut_bitmap(lut_pos, &lut_map, 32); + lut_mapped = map_bits(lut, 64, lut_map); - // X device - 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))) { - HERE(); - continue; - } - if (u64 & ~(0x000000B000600086ULL)) { - HERE(); - continue; - } + // lut6 + str = bool_bits2str(ULL_HIGH32(lut_mapped), 32); + if (!str) FAIL(EINVAL); + snprintf(lut6_buf, MAX_LUT_LEN, "(A6+~A6)*(%s)", str); + *lut6_p = lut6_buf; - dev_idx = fpga_dev_idx(es->model, y, x, DEV_LOGIC, DEV_LOG_X); - if (dev_idx == NO_DEV) FAIL(EINVAL); - *(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0; + // lut5 + str = bool_bits2str(ULL_LOW32(lut_mapped), 32); + if (!str) FAIL(EINVAL); + strcpy(lut5_buf, str); + *lut5_p = lut5_buf; + } else { + xc6_lut_bitmap(lut_pos, &lut_map, 64); + lut_mapped = map_bits(lut, 64, lut_map); + str = bool_bits2str(lut_mapped, 64); + if (!str) FAIL(EINVAL); + strcpy(lut6_buf, str); + *lut6_p = lut6_buf; + } + return 0; +fail: + return rc; +} - // A6_LUT - u64 = read_lut64(u8_p + 27*FRAME_SIZE, (byte_off+4)*8); - if (!u64) lut_str = 0; - else { - int logic_base[6] = {1,1,0,1,1,0}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); - } - if (lut_str && *lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X, - LUT_A, 6, lut_str, ZTERM); - if (rc) FAIL(rc); - *(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off+4) = 0; - *(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off+4) = 0; - } - // B6_LUT - u64 = read_lut64(u8_p + 29*FRAME_SIZE, (byte_off+4)*8); - if (!u64) lut_str = 0; - else { - int logic_base[6] = {1,1,0,1,1,0}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); - } - if (lut_str && *lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X, - LUT_B, 6, lut_str, ZTERM); - *(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off+4) = 0; - *(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off+4) = 0; - } - // C6_LUT - u64 = read_lut64(u8_p + 27*FRAME_SIZE, byte_off*8); - if (!u64) lut_str = 0; - else { - int logic_base[6] = {0,1,0,0,0,1}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); - } - if (lut_str && *lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X, - LUT_C, 6, lut_str, ZTERM); - *(uint32_t*)(u8_p+27*FRAME_SIZE+byte_off) = 0; - *(uint32_t*)(u8_p+28*FRAME_SIZE+byte_off) = 0; - } - // D6_LUT - u64 = read_lut64(u8_p + 29*FRAME_SIZE, byte_off*8); - if (!u64) lut_str = 0; - else { - int logic_base[6] = {0,1,0,0,0,1}; - lut_str = lut2bool(u64, 64, &logic_base, /*flip_b0*/ 0); - } - if (lut_str && *lut_str) { - rc = fdev_logic_a2d_lut(es->model, y, x, DEV_LOG_X, - LUT_D, 6, lut_str, ZTERM); - *(uint32_t*)(u8_p+29*FRAME_SIZE+byte_off) = 0; - *(uint32_t*)(u8_p+30*FRAME_SIZE+byte_off) = 0; - } - } -#endif static int extract_logic(struct extract_state* es) { int row, row_pos, x, y, i, byte_off, last_minor, lut5_used, rc; - int ml_latch, x_latch; + int latch_ml, latch_x, l_col, lut; struct fpgadev_logic cfg_ml, cfg_x; uint64_t lut_X[4], lut_ML[4]; // LUT_A-LUT_D uint64_t mi20, mi23_M, mi2526; uint8_t* u8_p; + char lut6_ml[NUM_LUTS][MAX_LUT_LEN]; + char lut5_ml[NUM_LUTS][MAX_LUT_LEN]; + char lut6_x[NUM_LUTS][MAX_LUT_LEN]; + char lut5_x[NUM_LUTS][MAX_LUT_LEN]; for (x = LEFT_SIDE_WIDTH; x < es->model->x_width-RIGHT_SIDE_WIDTH; x++) { if (!is_atx(X_FABRIC_LOGIC_COL|X_CENTER_LOGIC_COL, es->model, x)) @@ -720,6 +619,13 @@ static int extract_logic(struct extract_state* es) byte_off = row_pos * 8; if (row_pos >= 8) byte_off += HCLK_BYTES; + // + // Step 1: + // + // read all configuration bits for the 2 logic devices + // into local variables + // + mi20 = frame_get_u64(u8_p + 20*FRAME_SIZE + byte_off) & XC6_MI20_LOGIC_MASK; if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M)) { mi23_M = frame_get_u64(u8_p + 23*FRAME_SIZE + byte_off); @@ -732,6 +638,7 @@ static int extract_logic(struct extract_state* es) lut_X[LUT_B] = frame_get_lut64(u8_p + 29*FRAME_SIZE, row_pos*2+1); lut_X[LUT_C] = frame_get_lut64(u8_p + 27*FRAME_SIZE, row_pos*2); lut_X[LUT_D] = frame_get_lut64(u8_p + 29*FRAME_SIZE, row_pos*2); + l_col = 0; } else if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_L)) { mi23_M = 0; mi2526 = frame_get_u64(u8_p + 25*FRAME_SIZE + byte_off); @@ -743,19 +650,36 @@ static int extract_logic(struct extract_state* es) lut_X[LUT_B] = frame_get_lut64(u8_p + 28*FRAME_SIZE, row_pos*2+1); lut_X[LUT_C] = frame_get_lut64(u8_p + 26*FRAME_SIZE, row_pos*2); lut_X[LUT_D] = frame_get_lut64(u8_p + 28*FRAME_SIZE, row_pos*2); + l_col = 1; } else { HERE(); continue; } + + // + // Step 2: + // + // If all is zero, assume the devices are not instantiated. + // todo: we could check pin connectivity and infer 0-bit + // configured devices + // + if (!mi20 && !mi23_M && !mi2526 && !lut_X[0] && !lut_X[1] && !lut_X[2] && !lut_X[3] && !lut_ML[0] && !lut_ML[1] && !lut_ML[2] && !lut_ML[3]) continue; + // + // Step 3: + // + // Parse all bits from minors 20 and 25/26 into more + // easily usable cfg_ml and cfg_x structures. + // + memset(&cfg_ml, 0, sizeof(cfg_ml)); memset(&cfg_x, 0, sizeof(cfg_x)); - ml_latch = 0; - x_latch = 0; + latch_ml = 0; + latch_x = 0; // minor20 if (mi20 & (1ULL<model, y, x, DEV_LOGIC, LOGIC_L)) { + if (l_col) { HERE(); continue; } @@ -880,7 +804,7 @@ static int extract_logic(struct extract_state* es) mi2526 &= ~(1ULL<model, y, x, DEV_LOGIC, LOGIC_M)) { + if (!l_col) { HERE(); continue; } @@ -1107,34 +1031,45 @@ static int extract_logic(struct extract_state* es) mi2526 &= ~(1ULL<model, y, x, DEV_LOGIC, LOGIC_M) ? 30 : 29; + last_minor = l_col ? 29 : 30; for (i = 21; i <= last_minor; i++) frame_set_u64(u8_p + i*FRAME_SIZE + byte_off, 0); - // instantiate configuration + // + // Step 9: + // + // Instantiate configuration. + // + if (!all_zero(&cfg_ml, sizeof(cfg_ml))) { rc = fdev_logic_setconf(es->model, y, x, DEV_LOG_M_OR_L, &cfg_ml); if (rc) FAIL(rc); diff --git a/libs/helper.c b/libs/helper.c index a0bfac4..e3392b4 100644 --- a/libs/helper.c +++ b/libs/helper.c @@ -178,15 +178,15 @@ fail: return -1; } -uint64_t map_bits(uint64_t u64, int num_bits, int* dest_pos) +uint64_t map_bits(uint64_t u64, int num_bits, int* src_pos) { uint64_t result; int i; result = 0; for (i = 0; i < num_bits; i++) { - if (u64 & (1ULL< empty string - if (mt_size[0] == 0) { - str[0] = 0; - return str; - } - - // go through five rounds of merging - for (round = 1; round < 7; round++) { - for (i = 0; i < mt_size[round-1]; i++) { - for (j = i+1; j < mt_size[round-1]; j++) { - only_diff_bit = -1; - for (k = 0; k < 6; k++) { - if (mt[round-1][i].a[k] != mt[round-1][j].a[k]) { - if (only_diff_bit != -1) { - only_diff_bit = -1; - break; - } - only_diff_bit = k; - } - } - if (only_diff_bit != -1) { - char new_term[6]; - - for (k = 0; k < 6; k++) - new_term[k] = - (k == only_diff_bit) ? 2 - : mt[round-1][i].a[k]; - for (k = 0; k < mt_size[round]; k++) { - if (new_term[0] == mt[round][k].a[0] - && new_term[1] == mt[round][k].a[1] - && new_term[2] == mt[round][k].a[2] - && new_term[3] == mt[round][k].a[3] - && new_term[4] == mt[round][k].a[4] - && new_term[5] == mt[round][k].a[5]) - break; - } - if (k >= mt_size[round]) { - mt[round][mt_size[round]].a[0] = new_term[0]; - mt[round][mt_size[round]].a[1] = new_term[1]; - mt[round][mt_size[round]].a[2] = new_term[2]; - mt[round][mt_size[round]].a[3] = new_term[3]; - mt[round][mt_size[round]].a[4] = new_term[4]; - mt[round][mt_size[round]].a[5] = new_term[5]; - mt_size[round]++; - } - mt[round-1][i].merged = 1; - mt[round-1][j].merged = 1; - } - } - } - } - // special case: 222222 -> (A6+~A6) - for (i = 0; i < mt_size[6]; i++) { - if (mt[6][i].a[0] == 2 - && mt[6][i].a[1] == 2 - && mt[6][i].a[2] == 2 - && mt[6][i].a[3] == 2 - && mt[6][i].a[4] == 2 - && mt[6][i].a[5] == 2) { - strcpy(str, "A6+~A6"); - return str; - } - } - - str_end = 0; - for (round = 0; round < 7; round++) { - for (i = 0; i < mt_size[round]; i++) { - if (!mt[round][i].merged) { - if (str_end) - str[str_end++] = '+'; - first_op = 1; - for (j = 0; j < 6; j++) { - if (mt[round][i].a[j] != 2) { - if (!first_op) - str[str_end++] = '*'; - if (!mt[round][i].a[j]) - str[str_end++] = '~'; - str[str_end++] = 'A'; - str[str_end++] = '1' + j; - first_op = 0; - } - } - } - } - } - str[str_end] = 0; - // TODO: This could be further simplified, see Petrick's method. - // XOR don't simplify well, try A2@A3 - return str; -} - int printf_iob(uint8_t* d, int len, int inpos, int num_entries) { int i, num_printed; @@ -829,24 +693,6 @@ void printf_extrabits(const uint8_t* maj_bits, int start_minor, int num_minors, } } -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, bit_off_in_frame+j*2)) - lut64 |= 1LL << (j*4); - 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], bit_off_in_frame+j*2)) - lut64 |= 1LL << (j*4+2); - if (frame_get_bit(&two_minors[130], bit_off_in_frame+(j*2)+1)) - lut64 |= 1LL << (j*4+3); - } - return lut64; -} - void write_lut64(uint8_t* two_minors, int off_in_frame, uint64_t u64) { int i; @@ -986,31 +832,6 @@ int all_zero(const void* d, int num_bytes) return 1; } -int get_nibble(uint64_t u64, int nibble_bit0_off) -{ - int n, i; - - n = 0; - for (i = 0; i < 4; i++) { - if (u64 & (1ULL << (nibble_bit0_off+i))) - n |= 1<