From c330b8e11f54a5fb79cd08a0636a8aa5ab2e7a87 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Fri, 12 Oct 2012 10:18:47 +0200 Subject: [PATCH] carry chain fixes --- autotest.c | 62 +++++++++++++++++---------------------- libs/bit_frames.c | 69 ++++++++++++++++++++++++++++++++++++++++++-- libs/control.c | 8 ++--- libs/helper.c | 3 +- libs/helper.h | 1 + libs/model.h | 2 +- libs/model_devices.c | 10 +++---- libs/parts.c | 3 ++ libs/parts.h | 1 + 9 files changed, 108 insertions(+), 51 deletions(-) diff --git a/autotest.c b/autotest.c index 1444ca9..319e955 100644 --- a/autotest.c +++ b/autotest.c @@ -1012,7 +1012,7 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx, } } - // add stub nets for each required pin + // add one stub net per required pin dev = fdev_p(tstate->model, y, x, DEV_LOGIC, type_idx); if (!dev) FAIL(EINVAL); for (i = 0; i < dev->pinw_req_total; i++) { @@ -1022,6 +1022,30 @@ static int test_logic(struct test_state* tstate, int y, int x, int type_idx, rc = fnet_add_port(tstate->model, pinw_nets[i], y, x, DEV_LOGIC, type_idx, dev->pinw_req_for_cfg[i]); if (rc) FAIL(rc); + if (dev->pinw_req_for_cfg[i] == LI_CIN) { + int connpt_dests_o, num_dests, cout_y, cout_x; + str16_t cout_str; + swidx_t cout_sw; + + if ((fpga_connpt_find(tstate->model, y, x, + dev->pinw[LI_CIN], &connpt_dests_o, + &num_dests) == NO_CONN) + || num_dests != 1) { + HERE(); + } else { + fpga_conn_dest(tstate->model, y, x, + connpt_dests_o, &cout_y, &cout_x, &cout_str); + cout_sw = fpga_switch_first(tstate->model, + cout_y, cout_x, cout_str, SW_TO); + if (cout_sw == NO_SWITCH) HERE(); + else { + rc = fnet_add_sw(tstate->model, + pinw_nets[i], cout_y, cout_x, + &cout_sw, /*num_sw*/ 1); + if (rc) FAIL(rc); + } + } + } if ((dev->pinw_req_for_cfg[i] == LI_A6 && dev->u.logic.a2d[LUT_A].lut5 && *dev->u.logic.a2d[LUT_A].lut5) @@ -1247,7 +1271,8 @@ static int test_logic_config(struct test_state* tstate) tstate->diff_to_null = 1; - y = 68; + // For cin/cout testing, pick a y that is not at the bottom. + y = 67; for (x_i = 0; x_i < sizeof(x_enum)/sizeof(*x_enum); x_i++) { for (type_i = 0; type_i < sizeof(idx_enum)/sizeof(*idx_enum); type_i++) { for (lut = LUT_A; lut <= LUT_D; lut++) { @@ -1693,39 +1718,6 @@ int main(int argc, char** argv) // for example: ./autotest 2>&1 | tee autotest.log setvbuf(stdout, /*buf*/ 0, _IOLBF, /*size*/ 0); -#if 0 -int lut_map1[64] = {63,62,61,60,59,58,57,56,55,54,53,52,51,50, - 49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31, - 30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, - 9,8,7,6,5,4,3,2,1,0}; -//int bool_str2bits(const char* str, uint64_t* u64, int num_bits); -//const char* bool_bits2str(uint64_t u64, int num_bits); -{ - uint64_t u64, u64_2; - - rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*~A1", &u64, 64); - printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64)); - rc = bool_str2bits("~A6*~A5*~A4*~A3*~A2*A1", &u64, 64); - printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64)); - rc = bool_str2bits("A6*A5*A4*A3*A2*A1", &u64, 64); - printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64)); - rc = bool_str2bits("A5*A4*A3*A2*A1", &u64, 32); - printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32)); - rc = bool_str2bits("A4*A3", &u64, 32); - printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32)); - rc = bool_str2bits("A1", &u64, 64); - printf("rc %i u64 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 64)); - rc = bool_str2bits("A1", &u64, 32); - printf("rc %i u32 %llX 2str %s\n", rc, u64, bool_bits2str(u64, 32)); - - u64 = 1; - u64_2 = map_bits(u64, 64, lut_map1); - printf("u %llX mapped %llX\n", u64, u64_2); - - return 0; -} -#endif - if (argc < 2) { printf_help(argv[0], available_tests); return 0; diff --git a/libs/bit_frames.c b/libs/bit_frames.c index 2016e89..efc7980 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -270,7 +270,9 @@ static int extract_iobs(struct extract_state* es) iob_sitename = get_iob_sitename(XC6SLX9, i); if (!iob_sitename) { - HERE(); + // The space for 6 IOBs on all four sides + // (6*8 = 48 bytes, *4=192 bytes) is used + // for clocks etc, so we ignore them here. continue; } rc = fpga_find_iob(es->model, iob_sitename, &iob_y, &iob_x, &iob_idx); @@ -1038,8 +1040,22 @@ static int extract_logic(struct extract_state* es) // instantiate the logic devices. // - if (mi20 || mi23_M || mi2526) { - HERE(); + if (mi20) { + fprintf(stderr, "#E %s:%i y%02i x%02i l%i " + "mi20 0x%016lX\n", + __FILE__, __LINE__, y, x, l_col, mi20); + continue; + } + if (mi23_M) { + fprintf(stderr, "#E %s:%i y%02i x%02i l%i " + "mi23_M 0x%016lX\n", + __FILE__, __LINE__, y, x, l_col, mi23_M); + continue; + } + if (mi2526) { + fprintf(stderr, "#E %s:%i y%02i x%02i l%i " + "mi2526 0x%016lX\n", + __FILE__, __LINE__, y, x, l_col, mi2526); continue; } @@ -1452,12 +1468,54 @@ fail: return rc; } +static int extract_logic_switches(struct extract_state* es, int y, int x) +{ + int row, row_pos, byte_off, minor, rc; + swidx_t sw_idx; + uint8_t* u8_p; + + row = which_row(y, es->model); + row_pos = pos_in_row(y, es->model); + if (row == -1 || row_pos == -1 || row_pos == 8) FAIL(EINVAL); + if (row_pos > 8) row_pos--; + u8_p = get_first_minor(es->bits, row, es->model->x_major[x]); + byte_off = row_pos * 8; + if (row_pos >= 8) byte_off += HCLK_BYTES; + + if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M)) + minor = 26; + else if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_L)) + minor = 25; + else + FAIL(EINVAL); + + if (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW)) { + sw_idx = fpga_switch_lookup(es->model, y, x, + strarray_find(&es->model->str, "M_COUT"), + strarray_find(&es->model->str, "M_COUT_N")); + if (sw_idx == NO_SWITCH) { HERE(); return 0; } + + if (es->num_yx_pos >= MAX_YX_SWITCHES) + { FAIL(ENOTSUP); } + es->yx_pos[es->num_yx_pos].y = y; + es->yx_pos[es->num_yx_pos].x = x; + es->yx_pos[es->num_yx_pos].idx = sw_idx; + es->num_yx_pos++; + + frame_clear_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW); + } + return 0; +fail: + return rc; +} + static int extract_switches(struct extract_state* es) { int x, y, rc; for (x = 0; x < es->model->x_width; x++) { for (y = 0; y < es->model->y_height; y++) { + // routing switches if (is_atx(X_ROUTING_COL, es->model, x) && y >= TOP_IO_TILES && y < es->model->y_height-BOT_IO_TILES @@ -1466,6 +1524,11 @@ static int extract_switches(struct extract_state* es) rc = extract_routing_switches(es, y, x); if (rc) FAIL(rc); } + // logic switches + if (has_device(es->model, y, x, DEV_LOGIC)) { + rc = extract_logic_switches(es, y, x); + if (rc) FAIL(rc); + } } } return 0; diff --git a/libs/control.c b/libs/control.c index 365b763..766e414 100644 --- a/libs/control.c +++ b/libs/control.c @@ -887,11 +887,8 @@ int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type, add_req_inpin(dev, LI_CE); if (dev->u.logic.sr_used) add_req_inpin(dev, LI_SR); - if (dev->u.logic.cout_used) { + if (dev->u.logic.cout_used) add_req_outpin(dev, LO_COUT); - if (!dev->u.logic.precyinit) - add_req_inpin(dev, LI_CIN); - } if (dev->u.logic.precyinit == PRECYINIT_AX) add_req_inpin(dev, LI_AX); if (dev->u.logic.a2d[LUT_A].out_mux == MUX_F7 @@ -1537,7 +1534,8 @@ int fpga_switch_chain(struct sw_chain* ch) idx = fpga_switch_backtofirst(ch->model, ch->y, ch->x, ch->set.sw[ch->set.len-1], ch->from_to); if (idx == NO_SWITCH) { - HERE(); goto internal_error; + ch->set.len = 0; + return NO_SWITCH; } #ifdef DBG_ENUM_SWITCH printf("back_to_first from %s to %s\n", diff --git a/libs/helper.c b/libs/helper.c index e3392b4..79427a8 100644 --- a/libs/helper.c +++ b/libs/helper.c @@ -359,8 +359,7 @@ int printf_iob(uint8_t* d, int len, int inpos, int num_entries) for (i = 0; i < num_entries; i++) { u64 = frame_get_u64(&d[inpos+i*8]); if (u64) { - printf("iob i%i 0x%016llX\n", i, - (long long unsigned) u64); + printf("iob i%i 0x%016lX\n", i, u64); num_printed++; } } diff --git a/libs/helper.h b/libs/helper.h index 28db9c4..1c6e2f5 100644 --- a/libs/helper.h +++ b/libs/helper.h @@ -25,6 +25,7 @@ __FILE__, __LINE__) #define FAIL(code) do { HERE(); rc = (code); goto fail; } while (0) #define XOUT() do { HERE(); goto xout; } while (0) +#define CHECK_MODEL(m) do { if ((m)->rc) return (m)->rc; } while (0) #define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF) diff --git a/libs/model.h b/libs/model.h index bc66bd4..295f42e 100644 --- a/libs/model.h +++ b/libs/model.h @@ -376,7 +376,7 @@ enum { LI_AX, LI_BX, LI_CX, LI_DX, LI_CLK, LI_CE, LI_SR, // only for L and M: - LI_CIN, // only some L and M devs have this + LI_CIN, // only for M: LI_WE, LI_AI, LI_BI, LI_CI, LI_DI, diff --git a/libs/model_devices.c b/libs/model_devices.c index 029bb18..1be89cd 100644 --- a/libs/model_devices.c +++ b/libs/model_devices.c @@ -510,11 +510,11 @@ static int init_logic(struct fpga_model* model, int y, int x, int idx) if (rc) FAIL(rc); } else tile->devs[idx].pinw[LI_WE] = STRIDX_NO_ENTRY; - if (tile->devs[idx].subtype != LOGIC_X - && ((is_atx(X_ROUTING_NO_IO, model, x-1) - && is_aty(Y_INNER_BOTTOM, model, y+1)) - || (!is_atx(X_ROUTING_NO_IO, model, x-1) - && is_aty(Y_BOT_INNER_IO, model, y+1)))) { + if (tile->devs[idx].subtype != LOGIC_X) { + // Wire connections will go to some CIN later + // (and must not warn about duplicates), but we + // have to add the connection point here so + // that pinw[LI_CIN] is initialized. rc = add_connpt_name(model, y, x, pf("%sCIN", pre), /*dup_warn*/ 1, &tile->devs[idx].pinw[LI_CIN], 0); diff --git a/libs/parts.c b/libs/parts.c index d125f7c..8e53009 100644 --- a/libs/parts.c +++ b/libs/parts.c @@ -11,6 +11,9 @@ const char* iob_xc6slx9_sitenames[IOB_WORDS*2/8] = { + // Note that the configuration space for 4*6 IOBs + // that are marked with 0 is used for clocks etc, + // just not IOBs. [0] "P70", "P69", "P67", "P66", "P65", "P64", "P62", "P61", "P60", "P59", "P58", "P57", "UNB113", "UNB114", "UNB115", "UNB116", diff --git a/libs/parts.h b/libs/parts.h index d93a097..1dd5aaa 100644 --- a/libs/parts.h +++ b/libs/parts.h @@ -323,6 +323,7 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits); #define XC6_ML_B_CY0_O5 56 // implies lut5 on ML-B #define XC6_ML_PRECYINIT_AX 57 #define XC6_X_A_FFSRINIT_1 58 +#define XC6_ML_COUT_CIN_SW 59 // ML_PRECYINIT=0 - #define XC6_ML_PRECYINIT_1 60 #define XC6_ML_B_FFSRINIT_1 61