From 3766d7f5fc037e23099e41574399a882cd22eedc Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Sat, 13 Oct 2012 02:40:30 +0200 Subject: [PATCH] several bug fixes --- autotest.c | 14 +++---- blinking_led.c | 2 +- libs/bit_frames.c | 96 +++++++++++++++++++++++++++++++++++------------ libs/control.c | 1 + libs/floorplan.c | 59 ++++++++++++++++------------- libs/helper.h | 8 ++-- libs/parts.c | 16 +++++++- libs/parts.h | 4 +- 8 files changed, 135 insertions(+), 65 deletions(-) diff --git a/autotest.c b/autotest.c index 319e955..ba25193 100644 --- a/autotest.c +++ b/autotest.c @@ -1228,7 +1228,7 @@ static int test_lut_encoding(struct test_state* tstate) if (rc) FAIL(rc); for (i = '1'; i <= '5'; i++) { sprintf(lut5_str, "A%c", i); - sprintf(lut6_str, "(A6+~A6)*%s", lut5_str); + sprintf(lut6_str, "(A6+~A6)*A%c", (i == '5') ? '1' : i+1); rc = test_logic(tstate, y, x_enum[x_i], idx_enum[type_i], &logic_cfg); if (rc) FAIL(rc); @@ -1540,22 +1540,22 @@ static int test_logic_config(struct test_state* tstate) if (idx_enum[type_i] == DEV_LOG_X) { // minimum-config X device memset(&logic_cfg, 0, sizeof(logic_cfg)); - logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*A3"; - logic_cfg.a2d[LUT_A].lut5 = "A3+A5"; + logic_cfg.a2d[LUT_A].lut6 = "(A6+~A6)*A1"; + logic_cfg.a2d[LUT_A].lut5 = "A2"; logic_cfg.a2d[LUT_A].out_mux = MUX_5Q; logic_cfg.a2d[LUT_A].ff5_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_A].ff = FF_FF; logic_cfg.a2d[LUT_A].ff_mux = MUX_O6; logic_cfg.a2d[LUT_A].ff_srinit = FF_SRINIT0; - logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*A3"; - logic_cfg.a2d[LUT_B].lut5 = "A3+A5"; + logic_cfg.a2d[LUT_B].lut6 = "(A6+~A6)*A4"; + logic_cfg.a2d[LUT_B].lut5 = "A3"; logic_cfg.a2d[LUT_B].out_mux = MUX_5Q; logic_cfg.a2d[LUT_B].ff5_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_B].ff = FF_FF; logic_cfg.a2d[LUT_B].ff_mux = MUX_O6; logic_cfg.a2d[LUT_B].ff_srinit = FF_SRINIT0; - logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*A3"; - logic_cfg.a2d[LUT_C].lut5 = "A3+A5"; + logic_cfg.a2d[LUT_C].lut6 = "(A6+~A6)*(A2+A5)"; + logic_cfg.a2d[LUT_C].lut5 = "A3+A4"; logic_cfg.a2d[LUT_C].out_mux = MUX_5Q; logic_cfg.a2d[LUT_C].ff5_srinit = FF_SRINIT0; logic_cfg.a2d[LUT_C].ff = FF_FF; diff --git a/blinking_led.c b/blinking_led.c index b844d33..71b9fe7 100644 --- a/blinking_led.c +++ b/blinking_led.c @@ -49,7 +49,7 @@ int main(int argc, char** argv) 8); #if 0 - logic_y = 68; + logic_y = 55-58 logic_x = 13; logic_type_idx = DEV_LOG_X; if ((rc = fdev_logic_a2d_lut(&model, logic_y, logic_x, logic_type_idx, diff --git a/libs/bit_frames.c b/libs/bit_frames.c index efc7980..a8f6284 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -92,6 +92,19 @@ struct extract_state struct sw_yxpos yx_pos[MAX_YX_SWITCHES]; // needs to be dynamically alloced... }; +static int find_es_switch(struct extract_state* es, int y, int x, swidx_t sw) +{ + int i; + if (sw == NO_CONN) { HERE(); return 0; } + for (i = 0; i < es->num_yx_pos; i++) { + if (es->yx_pos[i].y == y + && es->yx_pos[i].x == x + && es->yx_pos[i].idx == sw) + return 1; + } + return 0; +} + static int write_iobs(struct fpga_bits* bits, struct fpga_model* model) { int i, y, x, type_idx, part_idx, dev_idx, first_iob, rc; @@ -603,6 +616,7 @@ static int extract_logic(struct extract_state* es) char lut5_ml[NUM_LUTS][MAX_LUT_LEN]; char lut6_x[NUM_LUTS][MAX_LUT_LEN]; char lut5_x[NUM_LUTS][MAX_LUT_LEN]; + struct fpga_device* dev_ml; 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)) @@ -1065,7 +1079,13 @@ static int extract_logic(struct extract_state* es) // Do device-global sanity checking pre-LUT // -// todo: cfg_ml.cout_used must be determined from switches + // cfg_ml.cout_used + dev_ml = fdev_p(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L); + if (!dev_ml) FAIL(EINVAL); + if (find_es_switch(es, y, x, fpga_switch_first( + es->model, y, x, dev_ml->pinw[LO_COUT], SW_FROM))) + cfg_ml.cout_used = 1; + // todo: if srinit=1, the matching ff/latch must be on // todo: handle all_latch // todo: precyinit=0 has no bits @@ -1270,18 +1290,31 @@ static int extract_logic(struct extract_state* es) // todo: latch and2l and or2l need to be determined // from vcc connectivity, srinit etc. for (lut = LUT_A; lut <= LUT_D; lut++) { - if (cfg_ml.a2d[lut].ff_mux) + if (cfg_ml.a2d[lut].ff_mux) { cfg_ml.a2d[lut].ff = latch_ml ? FF_LATCH : FF_FF; - if (cfg_x.a2d[lut].ff_mux) + if (!cfg_ml.a2d[lut].ff_srinit) + cfg_ml.a2d[lut].ff_srinit = FF_SRINIT0; + if (!cfg_ml.clk_inv) + cfg_ml.clk_inv = CLKINV_CLK; + if (!cfg_ml.sync_attr) + cfg_ml.sync_attr = SYNCATTR_ASYNC; + } + if (cfg_x.a2d[lut].ff_mux) { cfg_x.a2d[lut].ff = latch_x ? FF_LATCH : FF_FF; + if (!cfg_x.a2d[lut].ff_srinit) + cfg_x.a2d[lut].ff_srinit = FF_SRINIT0; + if (!cfg_x.clk_inv) + cfg_x.clk_inv = CLKINV_CLK; + if (!cfg_x.sync_attr) + cfg_x.sync_attr = SYNCATTR_ASYNC; + } + // todo: ff5_srinit + // todo: 5Q ff also needs clock/sync check } - - // If any ff_mux (5 or 6) is set, check that we have - // a clock and sync attribute. Do this after the LUT - // checks because presence of a 'hard' clock/sync bit - // may signal ff presence there. -// todo: if a ff_mux is != 0, clk and sync must be set -// todo: if a ff/latch is on, either srinit1 or srinit0 must be set + // todo: + // if (lut_a->out_mux == xor || lut_a->ff_mux == xor + // || lut_a->acy0 != 0) && !precyinit && !cin_switch + // -> precyinit = precyinit_0 // // Step 8: @@ -1471,7 +1504,6 @@ fail: 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); @@ -1489,20 +1521,38 @@ static int extract_logic_switches(struct extract_state* es, int y, int x) 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 (frame_get_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_CIN_USED)) { + struct fpga_device* dev; + int connpt_dests_o, num_dests, cout_y, cout_x; + str16_t cout_str; + swidx_t cout_sw; - 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++; + dev = fdev_p(es->model, y, x, DEV_LOGIC, DEV_LOG_M_OR_L); + if (!dev) FAIL(EINVAL); - frame_clear_bit(u8_p + minor*FRAME_SIZE, byte_off*8 + XC6_ML_COUT_CIN_SW); + if ((fpga_connpt_find(es->model, y, x, + dev->pinw[LI_CIN], &connpt_dests_o, + &num_dests) == NO_CONN) + || num_dests != 1) { + HERE(); + } else { + fpga_conn_dest(es->model, y, x, connpt_dests_o, + &cout_y, &cout_x, &cout_str); + cout_sw = fpga_switch_first(es->model, cout_y, + cout_x, cout_str, SW_TO); + if (cout_sw == NO_SWITCH) HERE(); + else { + if (es->num_yx_pos >= MAX_YX_SWITCHES) + { FAIL(ENOTSUP); } + es->yx_pos[es->num_yx_pos].y = cout_y; + es->yx_pos[es->num_yx_pos].x = cout_x; + es->yx_pos[es->num_yx_pos].idx = cout_sw; + es->num_yx_pos++; + + frame_clear_bit(u8_p + minor*FRAME_SIZE, + byte_off*8 + XC6_ML_CIN_USED); + } + } } return 0; fail: diff --git a/libs/control.c b/libs/control.c index 766e414..8ad9a5b 100644 --- a/libs/control.c +++ b/libs/control.c @@ -1054,6 +1054,7 @@ swidx_t fpga_switch_first(struct fpga_model* model, int y, int x, int i, connpt_o; // Finds the first switch either from or to the name given. + if (name_i == STRIDX_NO_ENTRY) { HERE(); return NO_SWITCH; } tile = YX_TILE(model, y, x); for (i = 0; i < tile->num_switches; i++) { connpt_o = SW_I(tile->switches[i], from_to); diff --git a/libs/floorplan.c b/libs/floorplan.c index d655f29..e4761be 100644 --- a/libs/floorplan.c +++ b/libs/floorplan.c @@ -323,16 +323,30 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, } } cfg = &tile->devs[i].u.logic; - for (j = LUT_A; j <= LUT_D; j++) { - if (cfg->a2d[j].out_used) - fprintf(f, "%s %c_used\n", pref, 'A'+j); + for (j = LUT_D; j >= LUT_A; j--) { if (cfg->a2d[j].lut6 && cfg->a2d[j].lut6[0]) fprintf(f, "%s %c6_lut %s\n", pref, 'A'+j, cfg->a2d[j].lut6); if (cfg->a2d[j].lut5 && cfg->a2d[j].lut5[0]) fprintf(f, "%s %c5_lut %s\n", pref, 'A'+j, cfg->a2d[j].lut5); - + if (cfg->a2d[j].out_used) + fprintf(f, "%s %c_used\n", pref, 'A'+j); + switch (cfg->a2d[j].ff) { + case FF_OR2L: + fprintf(f, "%s %c_ff OR2L\n", pref, 'A'+j); + break; + case FF_AND2L: + fprintf(f, "%s %c_ff AND2L\n", pref, 'A'+j); + break; + case FF_LATCH: + fprintf(f, "%s %c_ff LATCH\n", pref, 'A'+j); + break; + case FF_FF: + fprintf(f, "%s %c_ff FF\n", pref, 'A'+j); + break; + case 0: break; default: FAIL(EINVAL); + } switch (cfg->a2d[j].ff_mux) { case MUX_O6: fprintf(f, "%s %c_ffmux O6\n", pref, 'A'+j); @@ -369,15 +383,6 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, break; case 0: break; default: FAIL(EINVAL); } - switch (cfg->a2d[j].ff5_srinit) { - case FF_SRINIT0: - fprintf(f, "%s %c5_ffsrinit 0\n", pref, 'A'+j); - break; - case FF_SRINIT1: - fprintf(f, "%s %c5_ffsrinit 1\n", pref, 'A'+j); - break; - case 0: break; default: FAIL(EINVAL); - } switch (cfg->a2d[j].out_mux) { case MUX_O6: fprintf(f, "%s %c_outmux O6\n", pref, 'A'+j); @@ -405,18 +410,12 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, break; case 0: break; default: FAIL(EINVAL); } - switch (cfg->a2d[j].ff) { - case FF_OR2L: - fprintf(f, "%s %c_ff OR2L\n", pref, 'A'+j); + switch (cfg->a2d[j].ff5_srinit) { + case FF_SRINIT0: + fprintf(f, "%s %c5_ffsrinit 0\n", pref, 'A'+j); break; - case FF_AND2L: - fprintf(f, "%s %c_ff AND2L\n", pref, 'A'+j); - break; - case FF_LATCH: - fprintf(f, "%s %c_ff LATCH\n", pref, 'A'+j); - break; - case FF_FF: - fprintf(f, "%s %c_ff FF\n", pref, 'A'+j); + case FF_SRINIT1: + fprintf(f, "%s %c5_ffsrinit 1\n", pref, 'A'+j); break; case 0: break; default: FAIL(EINVAL); } @@ -663,19 +662,25 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only) for (x = 0; x < model->x_width; x++) { for (y = 0; y < model->y_height; y++) { - rc = printf_IOB(f, model, y, x, config_only); if (rc) goto fail; + } + } + for (x = 0; x < model->x_width; x++) { + for (y = 0; y < model->y_height; y++) { rc = printf_LOGIC(f, model, y, x, config_only); if (rc) goto fail; - + } + } + for (x = 0; x < model->x_width; x++) { + for (y = 0; y < model->y_height; y++) { tile = YX_TILE(model, y, x); for (i = 0; i < tile->num_devs; i++) { if (config_only && !(tile->devs[i].instantiated)) continue; if (tile->devs[i].type == DEV_LOGIC || tile->devs[i].type == DEV_IOB) - continue; // handled above + continue; // handled earlier fprintf(f, "dev y%02i x%02i %s\n", y, x, fdev_type2str(tile->devs[i].type)); } diff --git a/libs/helper.h b/libs/helper.h index 1c6e2f5..942a79e 100644 --- a/libs/helper.h +++ b/libs/helper.h @@ -23,9 +23,9 @@ #define HERE() fprintf(stderr, "#E Internal error in %s:%i\n", \ __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 FAIL(code) do { HERE(); rc = (code); goto fail; } while (0) +#define XOUT() do { HERE(); goto xout; } while (0) +#define CHECK_RC(m) do { if ((m)->rc) return (m)->rc; } while (0) #define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF) @@ -85,7 +85,7 @@ void frame_set_u32(uint8_t* frame_d, uint32_t v); void frame_set_u64(uint8_t* frame_d, uint64_t v); uint64_t frame_get_lut64(const uint8_t* two_minors, int v32); -// In a lut pair, LOW32 is lut5, HIGH32 is lut6. +// In a lut pair, lut5 is always mapped to LOW32, lut6 to HIGH32. #define ULL_LOW32(v) ((uint32_t) (((uint64_t)v) & 0xFFFFFFFFULL)) #define ULL_HIGH32(v) ((uint32_t) (((uint64_t)v) >> 32)) void frame_set_lut64(uint8_t* two_minors, int v32, uint64_t v); diff --git a/libs/parts.c b/libs/parts.c index 8e53009..75df611 100644 --- a/libs/parts.c +++ b/libs/parts.c @@ -842,8 +842,20 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits) // expand from 32 to 64 for either lut6 only or lut5/lut6 pair. for (i = 0; i < 32; i++) { if (num_bits == 32) { - (*map)[i] = map32[i]%32; - (*map)[32+i] = 32+(*map)[i]; + if (lut_pos == XC6_LMAP_XM_M_A + || lut_pos == XC6_LMAP_XM_M_C + || lut_pos == XC6_LMAP_XM_X_A + || lut_pos == XC6_LMAP_XM_X_B + || lut_pos == XC6_LMAP_XL_L_B + || lut_pos == XC6_LMAP_XL_L_D + || lut_pos == XC6_LMAP_XL_X_A + || lut_pos == XC6_LMAP_XL_X_B) { + (*map)[i] = map32[i]%32; + (*map)[32+i] = 32+(map32[i]%32); + } else { + (*map)[i] = 32+(map32[i]%32); + (*map)[32+i] = map32[i]%32; + } } else { if (num_bits != 64) HERE(); (*map)[i] = map32[i]; diff --git a/libs/parts.h b/libs/parts.h index 1dd5aaa..3f127bc 100644 --- a/libs/parts.h +++ b/libs/parts.h @@ -323,7 +323,9 @@ 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 +// CIN_USED best corresponds to the cout->cout_n switch in the +// next lower logic device (y+1). +#define XC6_ML_CIN_USED 59 // ML_PRECYINIT=0 - #define XC6_ML_PRECYINIT_1 60 #define XC6_ML_B_FFSRINIT_1 61