From 340d011f0628adf939d99b6d267fb21382aa0d86 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Tue, 11 Dec 2012 21:47:50 -0500 Subject: [PATCH] more clock routing --- autotest.c | 101 ++++++++++++++++++++------- libs/bit_frames.c | 163 +++++++++++++++++++++++++++++++++----------- libs/control.c | 37 +++++----- libs/floorplan.c | 26 +++---- libs/helper.c | 33 +++++++-- libs/helper.h | 3 + libs/model.h | 7 +- libs/model_helper.c | 35 ++++++---- libs/parts.c | 11 +++ libs/parts.h | 5 ++ 10 files changed, 306 insertions(+), 115 deletions(-) diff --git a/autotest.c b/autotest.c index a72612a..0e2e98c 100644 --- a/autotest.c +++ b/autotest.c @@ -71,6 +71,11 @@ static int diff_printf(struct test_state* tstate) FILE* dest_f = 0; int rc; + if (tstate->cmdline_count != -1 + && tstate->next_diff_counter >= tstate->cmdline_skip + tstate->cmdline_count + 1) { + printf("\nO Finished %i tests.\n", tstate->cmdline_count); + exit(0); + } if (tstate->dry_run) { printf("O Dry run, skipping diff %i.\n", tstate->next_diff_counter++); return 0; @@ -79,11 +84,6 @@ static int diff_printf(struct test_state* tstate) printf("O Skipping diff %i.\n", tstate->next_diff_counter++); return 0; } - if (tstate->cmdline_count != -1 - && tstate->next_diff_counter >= tstate->cmdline_skip + tstate->cmdline_count + 1) { - printf("\nO Finished %i tests.\n", tstate->cmdline_count); - exit(0); - } snprintf(path, sizeof(path), "%s/autotest_%s_%06i", tstate->tmp_dir, tstate->base_name, tstate->next_diff_counter); @@ -970,7 +970,7 @@ static int test_iob_config(struct test_state* tstate) for (i = 0; (name = fpga_enum_iob(tstate->model, i, &iob_y, &iob_x, &iob_type_idx)); i++) { if (tstate->dry_run) - printf("IOB %s y%02i x%02i i%i\n", name, + printf("IOB %s y%i x%i i%i\n", name, iob_y, iob_x, iob_type_idx); rc = fdev_iob_IMUX(tstate->model, iob_y, iob_x, iob_type_idx, IMUX_I); @@ -1744,47 +1744,47 @@ static int test_clock_routing(struct test_state* tstate) { int rc, i, iob_clk_y, iob_clk_x, iob_clk_type_idx; int logic_y, logic_x, logic_type_idx; + int y; net_idx_t clock_net; tstate->diff_to_null = 1; + + // + // first round over all gclk pins to the same logic dev + // + for (i = 0; i < tstate->model->pkg->num_gclk_pins; i++) { if (!tstate->model->pkg->gclk_pin[i]) continue; - rc = fpga_find_iob(tstate->model, tstate->model->pkg->gclk_pin[i], + fpga_find_iob(tstate->model, tstate->model->pkg->gclk_pin[i], &iob_clk_y, &iob_clk_x, &iob_clk_type_idx); - if (rc) FAIL(rc); - printf("\nO test %i: gclk pin %s (y%02i x%02i IOB %i)\n", + RC_CHECK(tstate->model); + printf("\nO test %i: gclk pin %s (y%i x%i IOB %i)\n", tstate->next_diff_counter, tstate->model->pkg->gclk_pin[i], iob_clk_y, iob_clk_x, iob_clk_type_idx); - rc = fdev_iob_input(tstate->model, iob_clk_y, iob_clk_x, + fdev_iob_input(tstate->model, iob_clk_y, iob_clk_x, iob_clk_type_idx, IO_LVCMOS33); - if (rc) FAIL(rc); logic_y = 58; logic_x = 13; logic_type_idx = DEV_LOG_M_OR_L; - rc = fdev_logic_a2d_lut(tstate->model, logic_y, logic_x, + fdev_logic_a2d_lut(tstate->model, logic_y, logic_x, logic_type_idx, LUT_A, 6, "A1", ZTERM); - if (rc) FAIL(rc); - rc = fdev_set_required_pins(tstate->model, logic_y, logic_x, + + fdev_set_required_pins(tstate->model, logic_y, logic_x, DEV_LOGIC, logic_type_idx); - if (rc) FAIL(rc); - if (tstate->dry_run) fdev_print_required_pins(tstate->model, logic_y, logic_x, DEV_LOGIC, logic_type_idx); - rc = fnet_new(tstate->model, &clock_net); - if (rc) FAIL(rc); - rc = fnet_add_port(tstate->model, clock_net, iob_clk_y, + fnet_new(tstate->model, &clock_net); + RC_CHECK(tstate->model); + fnet_add_port(tstate->model, clock_net, iob_clk_y, iob_clk_x, DEV_IOB, iob_clk_type_idx, IOB_OUT_I); - if (rc) FAIL(rc); - rc = fnet_add_port(tstate->model, clock_net, logic_y, logic_x, + fnet_add_port(tstate->model, clock_net, logic_y, logic_x, DEV_LOGIC, logic_type_idx, LI_CLK); - if (rc) FAIL(rc); - rc = fnet_autoroute(tstate->model, clock_net); - if (rc) FAIL(rc); + fnet_autoroute(tstate->model, clock_net); if ((rc = diff_printf(tstate))) FAIL(rc); @@ -1794,6 +1794,59 @@ static int test_clock_routing(struct test_state* tstate) fdev_delete(tstate->model, iob_clk_y, iob_clk_x, DEV_IOB, iob_clk_type_idx); } + + // + // Second round over left and right gclk pins only (that's enough + // to reach all 16 gclk wires in the center). Then going to the + // left and right side of all hclk rows top-down. + // + + for (i = 0; i < tstate->model->pkg->num_gclk_pins; i++) { + if (!tstate->model->pkg->gclk_pin[i]) + continue; + fpga_find_iob(tstate->model, tstate->model->pkg->gclk_pin[i], + &iob_clk_y, &iob_clk_x, &iob_clk_type_idx); + RC_CHECK(tstate->model); + // skip top and bottom iobs + if (iob_clk_x != LEFT_OUTER_COL + && iob_clk_x != tstate->model->x_width-RIGHT_OUTER_O) + continue; + fdev_iob_input(tstate->model, iob_clk_y, iob_clk_x, + iob_clk_type_idx, IO_LVCMOS33); + + for (y = TOP_FIRST_REGULAR; y < tstate->model->y_height - BOT_LAST_REGULAR_O; y++) { + if (!is_aty(Y_ROW_HORIZ_AXSYMM, tstate->model, y)) + continue; + logic_type_idx = DEV_LOG_M_OR_L; + logic_y = y-3; + for (logic_x = 13; logic_x <= 26; logic_x += 13) { + fdev_logic_a2d_lut(tstate->model, logic_y, logic_x, + logic_type_idx, LUT_A, 6, "A1", ZTERM); + + fdev_set_required_pins(tstate->model, logic_y, logic_x, + DEV_LOGIC, logic_type_idx); + if (tstate->dry_run) + fdev_print_required_pins(tstate->model, + logic_y, logic_x, DEV_LOGIC, logic_type_idx); + + fnet_new(tstate->model, &clock_net); + RC_CHECK(tstate->model); + fnet_add_port(tstate->model, clock_net, iob_clk_y, + iob_clk_x, DEV_IOB, iob_clk_type_idx, IOB_OUT_I); + fnet_add_port(tstate->model, clock_net, logic_y, logic_x, + DEV_LOGIC, logic_type_idx, LI_CLK); + fnet_autoroute(tstate->model, clock_net); + + if ((rc = diff_printf(tstate))) FAIL(rc); + + fnet_delete(tstate->model, clock_net); + fdev_delete(tstate->model, logic_y, logic_x, DEV_LOGIC, + logic_type_idx); + } + } + fdev_delete(tstate->model, iob_clk_y, iob_clk_x, DEV_IOB, + iob_clk_type_idx); + } return 0; fail: return rc; diff --git a/libs/bit_frames.c b/libs/bit_frames.c index 6f26eae..de12484 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -9,8 +9,6 @@ #include "bit.h" #include "control.h" -#define HCLK_BYTES 2 - static uint8_t* get_first_minor(struct fpga_bits* bits, int row, int major) { int i, num_frames; @@ -709,7 +707,7 @@ static int extract_logic(struct extract_state* es) 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 (row_pos >= 8) byte_off += XC6_HCLK_BYTES; // // Step 1: @@ -1131,19 +1129,19 @@ static int extract_logic(struct extract_state* es) // if (mi20) { - fprintf(stderr, "#E %s:%i y%02i x%02i l%i " + fprintf(stderr, "#E %s:%i y%i x%i 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 " + fprintf(stderr, "#E %s:%i y%i x%i 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 " + fprintf(stderr, "#E %s:%i y%i x%i l%i " "mi2526 0x%016lX\n", __FILE__, __LINE__, y, x, l_col, mi2526); continue; @@ -1609,7 +1607,7 @@ static int extract_logic_switches(struct extract_state* es, int y, int x) 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 (row_pos >= 8) byte_off += XC6_HCLK_BYTES; if (has_device_type(es->model, y, x, DEV_LOGIC, LOGIC_M)) minor = 26; @@ -1792,13 +1790,37 @@ struct iologic_sw_pos s_bot_outer_io_swpos[] = {{0}} }; +static int add_yx_switch(struct extract_state *es, + int y, int x, const char *from, const char *to) +{ + str16_t from_str_i, to_str_i; + swidx_t sw_idx; + + RC_CHECK(es->model); + + from_str_i = strarray_find(&es->model->str, from); + to_str_i = strarray_find(&es->model->str, to); + RC_ASSERT(es->model, from_str_i != STRIDX_NO_ENTRY + && to_str_i != STRIDX_NO_ENTRY); + + sw_idx = fpga_switch_lookup(es->model, y, x, + from_str_i, to_str_i); + RC_ASSERT(es->model, sw_idx != NO_SWITCH); + + RC_ASSERT(es->model, es->num_yx_pos < MAX_YX_SWITCHES); + 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++; + + RC_RETURN(es->model); +} + static int extract_iologic_switches(struct extract_state* es, int y, int x) { int row_num, row_pos, bit_in_frame, i, j, rc; uint8_t* minor0_p; struct iologic_sw_pos* sw_pos; - str16_t from_str_i, to_str_i; - swidx_t sw_idx; RC_CHECK(es->model); // From y/x coordinate, determine major, row, bit offset @@ -1837,23 +1859,8 @@ static int extract_iologic_switches(struct extract_state* es, int y, int x) } if (!j || sw_pos[i].minor[j] != -1) continue; - for (j = 0; j < MAX_IOLOGIC_SWBLOCK && sw_pos[i].to[j]; j++) { - from_str_i = strarray_find(&es->model->str, sw_pos[i].from[j]); - to_str_i = strarray_find(&es->model->str, sw_pos[i].to[j]); - if (from_str_i == STRIDX_NO_ENTRY - || to_str_i == STRIDX_NO_ENTRY) - FAIL(EINVAL); - sw_idx = fpga_switch_lookup(es->model, y, x, - from_str_i, to_str_i); - if (sw_idx == NO_SWITCH) FAIL(EINVAL); - - 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++; - } + for (j = 0; j < MAX_IOLOGIC_SWBLOCK && sw_pos[i].to[j]; j++) + add_yx_switch(es, y, x, sw_pos[i].from[j], sw_pos[i].to[j]); for (j = 0; sw_pos[i].minor[j] != -1; j++) frame_clear_bit(&minor0_p[sw_pos[i].minor[j] *FRAME_SIZE], bit_in_frame+sw_pos[i].b64[j]); @@ -1867,9 +1874,88 @@ fail: return rc; } -static int extract_switches(struct extract_state* es) +static int extract_center_switches(struct extract_state *es) { - int x, y, rc; + int center_row, center_major, word, i; + uint8_t *minor_p; + + RC_CHECK(es->model); + center_row = es->model->die->num_rows/2; + center_major = xc_die_center_major(es->model->die); + minor_p = get_first_minor(es->bits, center_row, + center_major) + XC6_CENTER_GCLK_MINOR*FRAME_SIZE; + word = frame_get_pinword(minor_p + 15*8+XC6_HCLK_BYTES); + if (word) { + for (i = 0; i < 16; i++) { + if (!(word & (1<model->center_y, es->model->center_x, + pf("CLKC_CKLR%i", i), pf("CLKC_GCLK%i", i)); + } + frame_set_pinword(minor_p + 15*8+XC6_HCLK_BYTES, 0); + } + word = frame_get_pinword(minor_p + 15*8+XC6_HCLK_BYTES + XC6_WORD_BYTES); + if (word) { + for (i = 0; i < 16; i++) { + if (!(word & (1<model->center_y, es->model->center_x, + pf("CLKC_CKTB%i", i), pf("CLKC_GCLK%i", i)); + } + frame_set_pinword(minor_p + 15*8+XC6_HCLK_BYTES + XC6_WORD_BYTES, 0); + } + RC_RETURN(es->model); +} + +static int extract_hclk_switches(struct extract_state *es) +{ + int word, cur_row, cur_minor, cur_pin, i, hclk_y; + uint8_t *ma0_bits; + + RC_CHECK(es->model); + for (cur_row = 0; cur_row < es->model->die->num_rows; cur_row++) { + hclk_y = row_to_hclk(cur_row, es->model); + RC_ASSERT(es->model, hclk_y != -1); + ma0_bits = get_first_minor(es->bits, cur_row, XC6_NULL_MAJOR); + for (cur_minor = 0; cur_minor <= 2; cur_minor++) { + // left + word = frame_get_pinword(ma0_bits + cur_minor*FRAME_SIZE + 8*8+XC6_HCLK_BYTES); + if (word) { + for (i = 0; i <= 16/3; i++) { // 0-5 + cur_pin = cur_minor + i*3; + if (cur_pin > 15) break; + if (!(word & (1<model->center_x, + pf("CLKV_GCLKH_MAIN%i_FOLD", cur_pin), + pf("CLKV_GCLKH_L%i", cur_pin)); + word &= ~(1< 15) break; + if (!(word & (1<model->center_x, + pf("CLKV_GCLKH_MAIN%i_FOLD", cur_pin), + pf("CLKV_GCLKH_R%i", cur_pin)); + word &= ~(1<model); +} + +static int extract_switches(struct extract_state *es) +{ + int x, y; RC_CHECK(es->model); for (x = 0; x < es->model->x_width; x++) { @@ -1880,24 +1966,21 @@ static int extract_switches(struct extract_state* es) && y < es->model->y_height-BOT_IO_TILES && !is_aty(Y_ROW_HORIZ_AXSYMM|Y_CHIP_HORIZ_REGS, es->model, y)) { - rc = extract_routing_switches(es, y, x); - if (rc) FAIL(rc); + extract_routing_switches(es, y, x); } // logic switches if (has_device(es->model, y, x, DEV_LOGIC)) { - rc = extract_logic_switches(es, y, x); - if (rc) FAIL(rc); + extract_logic_switches(es, y, x); } // iologic switches if (has_device(es->model, y, x, DEV_ILOGIC)) { - rc = extract_iologic_switches(es, y, x); - if (rc) FAIL(rc); + extract_iologic_switches(es, y, x); } } } - return 0; -fail: - return rc; + extract_center_switches(es); + extract_hclk_switches(es); + RC_RETURN(es->model); } static int construct_extract_state(struct extract_state* es, @@ -2153,7 +2236,7 @@ static int write_iologic_sw(struct fpga_bits* bits, struct fpga_model* model, if (!str_sw[i].to_str) continue; fprintf(stderr, "#E %s:%i unsupported switch " - "y%02i x%02i %s -> %s\n", __FILE__, __LINE__, + "y%i x%i %s -> %s\n", __FILE__, __LINE__, y, x, str_sw[i].from_str, str_sw[i].to_str); } free(str_sw); @@ -2194,7 +2277,7 @@ static int write_switches(struct fpga_bits* bits, struct fpga_model* model) if (!(tile->switches[i] & SWITCH_USED)) continue; fprintf(stderr, "#E %s:%i unsupported switch " - "y%02i x%02i %s\n", __FILE__, __LINE__, + "y%i x%i %s\n", __FILE__, __LINE__, y, x, fpga_switch_print(model, y, x, i)); } @@ -2232,7 +2315,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model) 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; + if (row_pos >= 8) byte_off += XC6_HCLK_BYTES; if (xm_col) { // X device diff --git a/libs/control.c b/libs/control.c index 46ab58d..59d3b56 100644 --- a/libs/control.c +++ b/libs/control.c @@ -320,7 +320,7 @@ struct fpga_device* fdev_p(struct fpga_model* model, { dev_idx_t dev_idx = fpga_dev_idx(model, y, x, type, type_idx); if (dev_idx == NO_DEV) { - fprintf(stderr, "#E %s:%i fdev_p() y%02i x%02i type %i/%i not" + fprintf(stderr, "#E %s:%i fdev_p() y%i x%i type %i/%i not" " found\n", __FILE__, __LINE__, y, x, type, type_idx); return 0; } @@ -475,7 +475,7 @@ void fdev_print_required_pins(struct fpga_model* model, int y, int x, // and the caller should not suddenly be working with old // required pins when the print() function is not called. - printf("y%02i x%02i %s %i inpin", y, x, fdev_type2str(type), type_idx); + printf("y%i x%i %s %i inpin", y, x, fdev_type2str(type), type_idx); if (!dev->pinw_req_in) printf(" -\n"); else { @@ -484,7 +484,7 @@ void fdev_print_required_pins(struct fpga_model* model, int y, int x, printf("\n"); } - printf("y%02i x%02i %s %i outpin", y, x, fdev_type2str(type), type_idx); + printf("y%i x%i %s %i outpin", y, x, fdev_type2str(type), type_idx); if (dev->pinw_req_total <= dev->pinw_req_in) printf(" -\n"); else { @@ -1876,7 +1876,7 @@ void printf_swchain(struct fpga_model* model, int y, int x, struct sw_chain chain; int count = 0; - printf("printf_swchain() y%02i x%02i %s blist_len %i\n", + printf("printf_swchain() y%i x%i %s blist_len %i\n", y, x, strarray_lookup(&model->str, sw), block_list_len ? *block_list_len : 0); if (construct_sw_chain(&chain, model, y, x, sw, from_to, max_depth, @@ -1900,7 +1900,7 @@ void printf_swconns(struct fpga_model* model, int y, int x, if (construct_sw_conns(&conns, model, y, x, sw, from_to, max_depth)) { HERE(); return; } while (fpga_switch_conns(&conns) != NO_CONN) { - printf("sw %s conn y%02i x%02i %s\n", fmt_swset(model, y, x, + printf("sw %s conn y%i x%i %s\n", fmt_swset(model, y, x, &conns.chain.set, from_to), conns.dest_y, conns.dest_x, strarray_lookup(&model->str, conns.dest_str_i)); @@ -1919,7 +1919,7 @@ int fpga_switch_to_yx(struct switch_to_yx* p) RC_CHECK(p->model); #ifdef DBG_SWITCH_TO_YX - printf("fpga_switch_to_yx() %s y%02i-x%02i-%s yx_req %Xh flags %Xh\n", + printf("fpga_switch_to_yx() %s y%i-x%i-%s yx_req %Xh flags %Xh\n", p->from_to == SW_FROM ? "SW_FROM" : "SW_TO", p->y, p->x, strarray_lookup(&p->model->str, p->start_switch), p->yx_req, p->flags); @@ -1934,7 +1934,7 @@ int fpga_switch_to_yx(struct switch_to_yx* p) if (!is_atyx(p->yx_req, p->model, conns.dest_y, conns.dest_x)) continue; #ifdef DBG_SWITCH_TO_YX - printf(" sw %s conn y%02i x%02i %s\n", + printf(" sw %s conn y%i x%i %s\n", fmt_swset(p->model, p->y, p->x, &conns.chain.set, p->from_to), conns.dest_y, conns.dest_x, @@ -1977,10 +1977,10 @@ int fpga_switch_to_yx(struct switch_to_yx* p) void printf_switch_to_yx_result(struct switch_to_yx* p) { - printf("switch_to_yx() from y%02i x%02i connpt %s (%s)\n", + printf("switch_to_yx() from y%i x%i connpt %s (%s)\n", p->y, p->x, strarray_lookup(&p->model->str, p->start_switch), p->from_to == SW_FROM ? "SW_FROM" : "SW_TO"); - printf(" %s y%02i x%02i %s via %s\n", + printf(" %s y%i x%i %s via %s\n", p->from_to == SW_FROM ? "to" : "from", p->dest_y, p->dest_x, strarray_lookup(&p->model->str, p->dest_connpt), @@ -2032,7 +2032,7 @@ int fpga_switch_to_rel(struct switch_to_rel *p) RC_CHECK(p->model); #ifdef DBG_SWITCH_TO_REL - printf("fpga_switch_to_rel() %s y%02i-x%02i-%s flags %Xh rel_y %i rel_x %i target_connpt %s\n", + printf("fpga_switch_to_rel() %s y%i-x%i-%s flags %Xh rel_y %i rel_x %i target_connpt %s\n", p->from_to == SW_FROM ? "SW_FROM" : "SW_TO", p->start_y, p->start_x, strarray_lookup(&p->model->str, p->start_switch), p->flags, p->rel_y, p->rel_x, @@ -2046,12 +2046,17 @@ int fpga_switch_to_rel(struct switch_to_rel *p) best_y = -1; while (fpga_switch_conns(&conns) != NO_CONN) { #ifdef DBG_SWITCH_TO_REL - printf(" sw %s conn y%02i x%02i %s\n", + printf(" sw %s conn y%i x%i %s\n", fmt_swset(p->model, p->start_y, p->start_x, &conns.chain.set, p->from_to), conns.dest_y, conns.dest_x, strarray_lookup(&p->model->str, conns.dest_str_i)); #endif + // Do not continue with connections that do not lead to + // a switch. + if (fpga_switch_first(p->model, conns.dest_y, conns.dest_x, + conns.dest_str_i, SW_FROM) == NO_SWITCH) + continue; if (conns.dest_y != p->start_y + p->rel_y || conns.dest_x != p->start_x + p->rel_x) { if (!(p->flags & SWTO_REL_WEAK_TARGET)) @@ -2085,7 +2090,7 @@ int fpga_switch_to_rel(struct switch_to_rel *p) #ifdef DBG_SWITCH_TO_REL printf(" sw %s\n", fmt_swset(p->model, p->start_y, p->start_x, &best_set, p->from_to)); - printf(" dest y%02i-x%02i-%s\n", best_y, best_x, + printf(" dest y%i-x%i-%s\n", best_y, best_x, strarray_lookup(&p->model->str, best_connpt)); #endif p->set = best_set; @@ -2099,10 +2104,10 @@ int fpga_switch_to_rel(struct switch_to_rel *p) void printf_switch_to_rel_result(struct switch_to_rel* p) { - printf("switch_to_rel() from y%02i x%02i connpt %s (%s)\n", + printf("switch_to_rel() from y%i x%i connpt %s (%s)\n", p->start_y, p->start_x, strarray_lookup(&p->model->str, p->start_switch), p->from_to == SW_FROM ? "SW_FROM" : "SW_TO"); - printf(" %s y%02i x%02i %s via %s\n", + printf(" %s y%i x%i %s via %s\n", p->from_to == SW_FROM ? "to" : "from", p->dest_y, p->dest_x, strarray_lookup(&p->model->str, p->dest_connpt), @@ -2323,7 +2328,7 @@ static void fprintf_inout_pin(FILE* f, struct fpga_model* model, pin_str = fdev_pinw_idx2str(tile->devs[dev_idx].type, pinw_i); if (!pin_str) { HERE(); return; } - snprintf(buf, sizeof(buf), "net %i %s y%02i x%02i %s %i pin %s\n", + snprintf(buf, sizeof(buf), "net %i %s y%i x%i %s %i pin %s\n", net_i, in_pin ? "in" : "out", el->y, el->x, fdev_type2str(tile->devs[dev_idx].type), fdev_typeidx(model, el->y, el->x, dev_idx), @@ -2344,7 +2349,7 @@ void fnet_printf(FILE* f, struct fpga_model* model, net_idx_t net_i) continue; } // switch - fprintf(f, "net %i sw y%02i x%02i %s\n", + fprintf(f, "net %i sw y%i x%i %s\n", net_i, net->el[i].y, net->el[i].x, fpga_switch_print(model, net->el[i].y, net->el[i].x, net->el[i].idx)); diff --git a/libs/floorplan.c b/libs/floorplan.c index b631a40..e2484c3 100644 --- a/libs/floorplan.c +++ b/libs/floorplan.c @@ -31,11 +31,11 @@ int printf_tiles(FILE* f, struct fpga_model* model) tile = &model->tiles[y*model->x_width + x]; if (tile->type != NA) - fprintf(f, "tile y%02i x%02i name %s\n", y, x, + fprintf(f, "tile y%i x%i name %s\n", y, x, fpga_tiletype_str(tile->type)); if (tile->flags) { int tf = tile->flags; - fprintf(f, "tile y%02i x%02i flags", y, x); + fprintf(f, "tile y%i x%i flags", y, x); PRINT_FLAG(f, TF_FABRIC_ROUTING_COL); PRINT_FLAG(f, TF_FABRIC_LOGIC_XM_COL); @@ -79,7 +79,7 @@ static int printf_IOB(FILE* f, struct fpga_model* model, type_count++; continue; } - snprintf(pref, sizeof(pref), "dev y%02i x%02i IOB %i", + snprintf(pref, sizeof(pref), "dev y%i x%i IOB %i", y, x, type_count); type_count++; @@ -307,7 +307,7 @@ static int printf_LOGIC(FILE* f, struct fpga_model* model, type_count++; continue; } - snprintf(pref, sizeof(pref), "dev y%02i x%02i LOGIC %i", + snprintf(pref, sizeof(pref), "dev y%i x%i LOGIC %i", y, x, type_count); type_count++; @@ -676,7 +676,7 @@ static int printf_BUFGMUX(FILE* f, struct fpga_model* model, type_count++; continue; } - snprintf(pref, sizeof(pref), "dev y%02i x%02i BUFGMUX %i", + snprintf(pref, sizeof(pref), "dev y%i x%i BUFGMUX %i", y, x, type_count++); if (!config_only) fprintf(f, "%s\n", pref); @@ -767,7 +767,7 @@ static int printf_BUFIO(FILE* f, struct fpga_model* model, type_count++; continue; } - snprintf(pref, sizeof(pref), "dev y%02i x%02i BUFIO %i", + snprintf(pref, sizeof(pref), "dev y%i x%i BUFIO %i", y, x, type_count++); if (!config_only) fprintf(f, "%s\n", pref); @@ -847,7 +847,7 @@ static int printf_BSCAN(FILE* f, struct fpga_model* model, type_count++; continue; } - snprintf(pref, sizeof(pref), "dev y%02i x%02i BSCAN %i", + snprintf(pref, sizeof(pref), "dev y%i x%i BSCAN %i", y, x, type_count++); if (!config_only) fprintf(f, "%s\n", pref); @@ -940,7 +940,7 @@ int printf_devices(FILE* f, struct fpga_model* model, int config_only) || tile->devs[i].type == DEV_BUFIO || tile->devs[i].type == DEV_BSCAN) continue; // handled earlier - fprintf(f, "dev y%02i x%02i %s\n", y, x, + fprintf(f, "dev y%i x%i %s\n", y, x, fdev_type2str(tile->devs[i].type)); } } @@ -982,7 +982,7 @@ int printf_ports(FILE* f, struct fpga_model* model) first_port_printed = 1; fprintf(f, "\n"); } - fprintf(f, "port y%02i x%02i %s\n", + fprintf(f, "port y%i x%i %s\n", y, x, conn_point_name_src); } } @@ -1035,12 +1035,12 @@ int printf_conns(FILE* f, struct fpga_model* model) first_conn_printed = 1; fprintf(f, "\n"); } - sprintf(tmp_line, "conn y%02i x%02i %s ", + sprintf(tmp_line, "conn y%i x%i %s ", y, x, conn_point_name_src); k = strlen(tmp_line); while (k < 45) tmp_line[k++] = ' '; - sprintf(&tmp_line[k], "y%02i x%02i %s\n", + sprintf(&tmp_line[k], "y%i x%i %s\n", other_tile_y, other_tile_x, other_tile_connpt_str); fprintf(f, "%s", tmp_line); } @@ -1065,7 +1065,7 @@ int printf_switches(FILE* f, struct fpga_model* model) first_switch_printed = 1; fprintf(f, "\n"); } - fprintf(f, "sw y%02i x%02i %s\n", + fprintf(f, "sw y%i x%i %s\n", y, x, fpga_switch_print(model, y, x, i)); } } @@ -1249,7 +1249,7 @@ static void read_dev_line(struct fpga_model* model, const char* line, int start) dev_type_idx = to_i(&line[idx_beg], idx_end-idx_beg); dev_idx = fpga_dev_idx(model, y_coord, x_coord, dev_type, dev_type_idx); if (dev_idx == NO_DEV) { - fprintf(stderr, "%s:%i y%02i x%02i dev_type %i " + fprintf(stderr, "%s:%i y%i x%i dev_type %i " "dev_type_idx %i dev_idx %i\n", __FILE__, __LINE__, y_coord, x_coord, dev_type, dev_type_idx, dev_idx); diff --git a/libs/helper.c b/libs/helper.c index 78c7ee7..88054a5 100644 --- a/libs/helper.c +++ b/libs/helper.c @@ -495,6 +495,21 @@ void frame_set_bit(uint8_t *frame_d, int bit) frame_d[(bit/16)*2 + !((bit/8)%2)] |= v; } +// see ug380, table 2-5, bit ordering +int frame_get_pinword(const void *bits) +{ + int byte0, byte1; + byte0 = ((uint8_t*)bits)[0]; + byte1 = ((uint8_t*)bits)[1]; + return byte0 << 8 | byte1; +} + +void frame_set_pinword(void* bits, int v) +{ + ((uint8_t*)bits)[0] = v >> 8; + ((uint8_t*)bits)[1] = v & 0xFF; +} + uint8_t frame_get_u8(const uint8_t *frame_d) { uint8_t v = 0; @@ -504,6 +519,7 @@ uint8_t frame_get_u8(const uint8_t *frame_d) return v; } +// see ug380, table 2-5, bit ordering uint16_t frame_get_u16(const uint8_t *frame_d) { uint16_t high_b, low_b; @@ -608,6 +624,14 @@ void frame_set_lut64(uint8_t* two_minors, int v32, uint64_t v) frame_set_u32(&two_minors[FRAME_SIZE + off_in_frame], m1); } +// see ug380, table 2-5, bit ordering +static int xc6_bit2pin(int bit) +{ + int pin = bit % XC6_WORD_BITS; + if (pin >= 8) return 15-(pin-8); + return 7-pin; +} + int printf_frames(const uint8_t* bits, int max_frames, int row, int major, int minor, int print_empty, int no_clock) { @@ -645,9 +669,10 @@ int printf_frames(const uint8_t* bits, int max_frames, i_without_clk = i; if (i_without_clk >= 528) i_without_clk -= 16; - snprintf(suffix, sizeof(suffix), "64*%i+%i 256*%i+%i", + snprintf(suffix, sizeof(suffix), "64*%i+%i 256*%i+%i pin %i", i_without_clk/64, i_without_clk%64, - i_without_clk/256, i_without_clk%256); + i_without_clk/256, i_without_clk%256, + xc6_bit2pin(i_without_clk)); printf("%sbit %i %s\n", prefix, i, suffix); } return 1; @@ -664,8 +689,8 @@ void printf_clock(const uint8_t* frame, int row, int major, int minor) int i; for (i = 0; i < 16; i++) { if (frame_get_bit(frame, 512 + i)) - printf("r%i ma%i mi%i clock %i\n", - row, major, minor, i); + printf("r%i ma%i mi%i clock %i pin %i\n", + row, major, minor, i, xc6_bit2pin(i)); } } diff --git a/libs/helper.h b/libs/helper.h index 453c529..1e7200a 100644 --- a/libs/helper.h +++ b/libs/helper.h @@ -79,6 +79,9 @@ 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); +int frame_get_pinword(const void *bits); +void frame_set_pinword(void* bits, int v); + 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); diff --git a/libs/model.h b/libs/model.h index f50aeed..f1f7f57 100644 --- a/libs/model.h +++ b/libs/model.h @@ -306,10 +306,11 @@ void is_in_row(const struct fpga_model* model, int y, int* row_num, int* row_pos); // which_row() and pos_in_row() return -1 if y is outside of a row -int which_row(int y, struct fpga_model* model); -int pos_in_row(int y, struct fpga_model* model); +int which_row(int y, struct fpga_model *model); +int pos_in_row(int y, struct fpga_model *model); // regular_row_pos() returns the index (0..15) without hclk, or -1 if y is a hclk. -int regular_row_pos(int y, struct fpga_model* model); +int regular_row_pos(int y, struct fpga_model *model); +int row_to_hclk(int row, struct fpga_model *model); int y_to_hclk(int y, struct fpga_model *model); const char* logicin_s(int wire, int routing_io); diff --git a/libs/model_helper.c b/libs/model_helper.c index 6efd623..d724d0a 100644 --- a/libs/model_helper.c +++ b/libs/model_helper.c @@ -149,7 +149,7 @@ static int add_connpt_name_i(struct fpga_model *model, int y, int x, if (i < tile->num_conn_point_names) { if (warn_dup) fprintf(stderr, "Duplicate connection point name " - "y%02i x%02u %s\n", y, x, + "y%i x%i %s\n", y, x, strarray_lookup(&model->str, name_i)); } else // This is the first connection under name, add name. @@ -233,8 +233,8 @@ static int add_conn_uni_i(struct fpga_model *model, RC_CHECK(model); #ifdef DBG_ADD_CONN_UNI - fprintf(stderr, "add_conn_uni_i() from y%02i x%02i %s connpt %i" - " to y%02i x%02i %s\n", from_y, from_x, + fprintf(stderr, "add_conn_uni_i() from y%i x%i %s connpt %i" + " to y%i x%i %s\n", from_y, from_x, strarray_lookup(&model->str, from_name), *from_connpt_o, to_y, to_x, strarray_lookup(&model->str, to_name)); #endif @@ -257,12 +257,12 @@ static int add_conn_uni_i(struct fpga_model *model, if (tile->conn_point_dests[j*3] == to_x && tile->conn_point_dests[j*3+1] == to_y && tile->conn_point_dests[j*3+2] == to_name) { - fprintf(stderr, "Duplicate conn (num_conn_point_dests %i): y%02i x%02i %s - y%02i x%02i %s.\n", + fprintf(stderr, "Duplicate conn (num_conn_point_dests %i): y%i x%i %s - y%i x%i %s.\n", num_conn_point_dests_for_this_wire, from_y, from_x, strarray_lookup(&model->str, from_name), to_y, to_x, strarray_lookup(&model->str, to_name)); for (j = conn_start; j < conn_start + num_conn_point_dests_for_this_wire; j++) { - fprintf(stderr, "c%i: y%02i x%02i %s -> y%02i x%02i %s\n", j, + fprintf(stderr, "c%i: y%i x%i %s -> y%i x%i %s\n", j, from_y, from_x, strarray_lookup(&model->str, from_name), tile->conn_point_dests[j*3+1], tile->conn_point_dests[j*3], strarray_lookup(&model->str, tile->conn_point_dests[j*3+2])); @@ -288,10 +288,10 @@ static int add_conn_uni_i(struct fpga_model *model, for (j = (*from_connpt_o)+1; j < tile->num_conn_point_names; j++) tile->conn_point_names[j*2]++; #ifdef DBG_ADD_CONN_UNI - fprintf(stderr, " conn_point_dests for y%02i x%02i %s now:\n", + fprintf(stderr, " conn_point_dests for y%i x%i %s now:\n", from_y, from_x, strarray_lookup(&model->str, from_name)); for (j = conn_start; j < conn_start + num_conn_point_dests_for_this_wire+1; j++) { - fprintf(stderr, " c%i: y%02i x%02i %s -> y%02i x%02i %s\n", + fprintf(stderr, " c%i: y%i x%i %s -> y%i x%i %s\n", j, from_y, from_x, strarray_lookup(&model->str, from_name), tile->conn_point_dests[j*3+1], tile->conn_point_dests[j*3], strarray_lookup(&model->str, tile->conn_point_dests[j*3+2])); @@ -792,15 +792,9 @@ int regular_row_pos(int y, struct fpga_model* model) return row_pos; } -int y_to_hclk(int y, struct fpga_model *model) +int row_to_hclk(int row, struct fpga_model *model) { - int row_num, row_pos, hclk_pos; - - is_in_row(model, y, &row_num, &row_pos); - if (row_num == -1 - || row_pos == -1 || row_pos == HCLK_POS) - { HERE(); return -1; } - hclk_pos = model->y_height - BOT_LAST_REGULAR_O - row_num*ROW_SIZE - HCLK_POS; + int hclk_pos = model->y_height - BOT_LAST_REGULAR_O - row*ROW_SIZE - HCLK_POS; if (hclk_pos < model->center_y) hclk_pos--; // center regs if (hclk_pos < TOP_FIRST_REGULAR) @@ -808,6 +802,17 @@ int y_to_hclk(int y, struct fpga_model *model) return hclk_pos; } +int y_to_hclk(int y, struct fpga_model *model) +{ + int row_num, row_pos; + + is_in_row(model, y, &row_num, &row_pos); + if (row_num == -1 + || row_pos == -1 || row_pos == HCLK_POS) + { HERE(); return -1; } + return row_to_hclk(row_num, model); +} + const char* logicin_s(int wire, int routing_io) { if (routing_io && ((wire & LWF_WIRE_MASK) == X_A5 || (wire & LWF_WIRE_MASK) == X_B4)) diff --git a/libs/parts.c b/libs/parts.c index 1708360..dfcdd65 100644 --- a/libs/parts.c +++ b/libs/parts.c @@ -375,6 +375,17 @@ const struct xc_die *xc_die_info(int idcode) return 0; } +int xc_die_center_major(const struct xc_die *die) +{ + int i; + for (i = 0; i < die->num_majors; i++) { + if (die->majors[i].flags & XC_MAJ_CENTER) + return i; + } + HERE(); + return -1; +} + const struct xc6_pkg_info *xc6_pkg_info(enum xc6_pkg pkg) { // ug382 table 1-6 page 25 diff --git a/libs/parts.h b/libs/parts.h index 0148aa3..e99827e 100644 --- a/libs/parts.h +++ b/libs/parts.h @@ -95,6 +95,8 @@ struct xc_die const struct xc_die* xc_die_info(int idcode); +int xc_die_center_major(const struct xc_die *die); + enum xc6_pkg { TQG144, FTG256, CSG324, FGG484 }; #define XC6_NUM_GCLK_PINS 32 @@ -131,6 +133,8 @@ const struct xc6_pkg_info *xc6_pkg_info(enum xc6_pkg pkg); #define XC6_HCLK_BYTES 2 #define XC6_HCLK_BITS (XC6_HCLK_BYTES*8) +#define XC6_NULL_MAJOR 0 + #define XC6_IOB_MASK_IO 0x00FF00FFFF000000 #define XC6_IOB_MASK_IN_TYPE 0x000000000000F000 #define XC6_IOB_MASK_SLEW 0x0000000000FF0000 @@ -427,3 +431,4 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits); #define XC6_L_A_FFSRINIT_1 63 // L-device only #define XC6_TYPE2_GCLK_REG_SW 2 // bit 2 in 1st word +#define XC6_CENTER_GCLK_MINOR 25