diff --git a/README b/README index ebb4bb6..c9fe2ac 100644 --- a/README +++ b/README @@ -63,8 +63,8 @@ Design Principles TODO (as of January, 2013) short-term (1 month): +* support distributed and block memory * example: counter (including clock, jtag) -* support xc6slx9-ftg256 mid-term (6 months): * example: j1 soc diff --git a/autotest.c b/autotest.c index f6d65c9..4540561 100644 --- a/autotest.c +++ b/autotest.c @@ -1795,8 +1795,27 @@ static int test_dcm_config(struct test_state* tstate) static int test_bscan_config(struct test_state* tstate) { -// todo: not implemented + int bscan_y, bscan_x, bscan_type_idx, enum_i, rc; + int jtag_chain_i, jtag_test; + + enum_i = 0; + while (!(rc = fdev_enum(tstate->model, DEV_BSCAN, enum_i++, &bscan_y, + &bscan_x, &bscan_type_idx)) && bscan_y != -1) { + for (jtag_chain_i = 1; jtag_chain_i <= 4; jtag_chain_i++) { + for (jtag_test = 0; jtag_test <= 1; jtag_test++) { + rc = fdev_bscan(tstate->model, bscan_y, bscan_x, bscan_type_idx, + jtag_chain_i, jtag_test ? BSCAN_JTAG_TEST_Y : BSCAN_JTAG_TEST_N); + if (rc) FAIL(rc); + if ((rc = diff_printf(tstate))) FAIL(rc); + fdev_delete(tstate->model, bscan_y, bscan_x, DEV_BSCAN, bscan_type_idx); + if ((rc = diff_printf(tstate))) FAIL(rc); + } + } + } + if (rc) FAIL(rc); return 0; +fail: + return rc; } static int test_clock_routing(struct test_state* tstate) diff --git a/libs/bit_frames.c b/libs/bit_frames.c index cd43268..4406f1e 100644 --- a/libs/bit_frames.c +++ b/libs/bit_frames.c @@ -2217,6 +2217,80 @@ static void destruct_extract_state(struct extract_state *es) es->yx_pos = 0; } +static int extract_bscan(struct extract_state *es) +{ + int enum_i, bscan_y, bscan_x, bscan_type_idx; + int jtag_chain, jtag_test, pinword; + uint8_t *u8_p; + struct fpga_device *dev; + + RC_CHECK(es->model); + enum_i = 0; + while (!fdev_enum(es->model, DEV_BSCAN, enum_i++, &bscan_y, + &bscan_x, &bscan_type_idx) && bscan_y != -1) { + + u8_p = get_first_minor(es->bits, which_row(bscan_y, es->model), es->model->x_major[bscan_x]); + RC_ASSERT(es->model, u8_p); + pinword = frame_get_pinword(u8_p + XC6_BSCAN_MINOR*FRAME_SIZE + XC6_BSCAN_WORD*XC6_WORD_BYTES); + + if (!(pinword & (1 << ((bscan_y - TOP_IO_TILES)*2 + bscan_type_idx)))) + continue; + pinword &= ~(1 << ((bscan_y - TOP_IO_TILES)*2 + bscan_type_idx)); + + jtag_chain = 1; + jtag_test = BSCAN_JTAG_TEST_N; + if (bscan_y == TOP_IO_TILES && !bscan_type_idx + && (pinword & (1 << XC6_BSCAN_TEST_PIN))) { + pinword &= ~(1 << XC6_BSCAN_TEST_PIN); + jtag_test = BSCAN_JTAG_TEST_Y; + } + + if (pinword) { + HERE(); + continue; + } + dev = fdev_p(es->model, bscan_y, bscan_x, DEV_BSCAN, bscan_type_idx); + RC_ASSERT(es->model, dev); + if (dev->instantiated) { + HERE(); + continue; + } + fdev_bscan(es->model, bscan_y, bscan_x, bscan_type_idx, + jtag_chain, jtag_test); + RC_CHECK(es->model); + frame_set_pinword(u8_p + XC6_BSCAN_MINOR*FRAME_SIZE + XC6_BSCAN_WORD*XC6_WORD_BYTES, 0); + } + RC_RETURN(es->model); +} + +static int write_bscan(struct fpga_bits *bits, struct fpga_model *model) +{ + int enum_i, bscan_y, bscan_x, bscan_type_idx, pinword; + struct fpga_device *dev; + uint8_t *u8_p; + + RC_CHECK(model); + enum_i = 0; + while (!fdev_enum(model, DEV_BSCAN, enum_i++, &bscan_y, + &bscan_x, &bscan_type_idx) && bscan_y != -1) { + dev = fdev_p(model, bscan_y, bscan_x, DEV_BSCAN, bscan_type_idx); + RC_ASSERT(model, dev); + if (!dev->instantiated) continue; + + u8_p = get_first_minor(bits, which_row(bscan_y, model), model->x_major[bscan_x]); + RC_ASSERT(model, u8_p); + pinword = frame_get_pinword(u8_p + XC6_BSCAN_MINOR*FRAME_SIZE + XC6_BSCAN_WORD*XC6_WORD_BYTES); + + if (bscan_y == TOP_IO_TILES && !bscan_type_idx + && dev->u.bscan.jtag_test == BSCAN_JTAG_TEST_Y) + pinword |= 1 << XC6_BSCAN_TEST_PIN; + pinword |= 1 << ((bscan_y - TOP_IO_TILES)*2 + bscan_type_idx); + + frame_set_pinword(u8_p + XC6_BSCAN_MINOR*FRAME_SIZE + XC6_BSCAN_WORD*XC6_WORD_BYTES, pinword); + } + RC_RETURN(model); +} + int extract_model(struct fpga_model* model, struct fpga_bits* bits) { struct extract_state es; @@ -2241,6 +2315,8 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) if (rc) { RC_SET(model, rc); goto out; } rc = extract_logic(&es); if (rc) { RC_SET(model, rc); goto out; } + rc = extract_bscan(&es); + if (rc) { RC_SET(model, rc); goto out; } // turn switches into nets if (model->nets) @@ -3042,7 +3118,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model) RC_RETURN(model); } -int write_model(struct fpga_bits* bits, struct fpga_model* model) +int write_model(struct fpga_bits *bits, struct fpga_model *model) { int i; @@ -3053,6 +3129,7 @@ int write_model(struct fpga_bits* bits, struct fpga_model* model) write_switches(bits, model); write_type2(bits, model); write_logic(bits, model); + write_bscan(bits, model); RC_RETURN(model); } diff --git a/libs/control.c b/libs/control.c index 5ced012..ee8352c 100644 --- a/libs/control.c +++ b/libs/control.c @@ -80,21 +80,24 @@ const char *fpga_iob_sitename(struct fpga_model *model, static void enum_x(struct fpga_model *model, enum fpgadev_type type, int enum_i, int *y, int x, int *type_idx) { - int type_count, i, _y; + int tile_type_count, total_type_count, i, _y; struct fpga_tile* tile; - type_count = 0; + total_type_count = 0; + tile_type_count = 0; for (_y = 0; _y < model->y_height; _y++) { tile = YX_TILE(model, _y, x); + total_type_count += tile_type_count; + tile_type_count = 0; for (i = 0; i < tile->num_devs; i++) { if (tile->devs[i].type != type) continue; - if (type_count == enum_i) { + if (total_type_count + tile_type_count == enum_i) { *y = _y; - *type_idx = type_count; + *type_idx = tile_type_count; return; } - type_count++; + tile_type_count++; } } *y = -1; @@ -106,6 +109,7 @@ int fdev_enum(struct fpga_model* model, enum fpgadev_type type, int enum_i, struct fpga_tile* tile; int i, j, type_count; + *y = -1; RC_CHECK(model); switch (type) { case DEV_BUFGMUX: @@ -123,7 +127,6 @@ int fdev_enum(struct fpga_model* model, enum fpgadev_type type, int enum_i, } type_count++; } - *y = -1; RC_RETURN(model); case DEV_BUFIO: { int yx_pairs[] = { @@ -147,22 +150,20 @@ int fdev_enum(struct fpga_model* model, enum fpgadev_type type, int enum_i, type_count++; } } - *y = -1; RC_RETURN(model); } case DEV_PLL: case DEV_DCM: - enum_x(model, type, enum_i, y, model->center_x - - CENTER_CMTPLL_O, type_idx); + *x = model->center_x - CENTER_CMTPLL_O; + enum_x(model, type, enum_i, y, *x, type_idx); RC_RETURN(model); case DEV_BSCAN: - enum_x(model, type, enum_i, y, model->x_width - - RIGHT_IO_DEVS_O, type_idx); + *x = model->x_width - RIGHT_IO_DEVS_O; + enum_x(model, type, enum_i, y, *x, type_idx); RC_RETURN(model); default: break; } HERE(); - *y = -1; RC_RETURN(model); } @@ -840,25 +841,38 @@ fail: return rc; } -int fdev_bufgmux(struct fpga_model* model, int y, int x, +int fdev_bufgmux(struct fpga_model *model, int y, int x, int type_idx, int clk, int disable_attr, int s_inv) { - struct fpga_device* dev; + struct fpga_device *dev; int rc; RC_CHECK(model); dev = fdev_p(model, y, x, DEV_BUFGMUX, type_idx); - if (!dev) FAIL(EINVAL); + RC_ASSERT(model, dev); rc = reset_required_pins(dev); - if (rc) FAIL(rc); + if (rc) RC_FAIL(model, rc); dev->u.bufgmux.clk = clk; dev->u.bufgmux.disable_attr = disable_attr; dev->u.bufgmux.s_inv = s_inv; dev->instantiated = 1; - return 0; -fail: - return rc; + RC_RETURN(model); +} + +int fdev_bscan(struct fpga_model *model, int y, int x, int type_idx, + int jtag_chain, int jtag_test) +{ + struct fpga_device *dev; + + RC_CHECK(model); + dev = fdev_p(model, y, x, DEV_BSCAN, type_idx); + RC_ASSERT(model, dev); + + dev->u.bscan.jtag_chain = jtag_chain; + dev->u.bscan.jtag_test = jtag_test; + dev->instantiated = 1; + RC_RETURN(model); } static void scan_lut_digits(const char* s, int* digits) diff --git a/libs/control.h b/libs/control.h index 6e2f6dc..b3e3730 100644 --- a/libs/control.h +++ b/libs/control.h @@ -103,6 +103,9 @@ int fdev_iob_drive(struct fpga_model* model, int y, int x, int fdev_bufgmux(struct fpga_model* model, int y, int x, int type_idx, int clk, int disable_attr, int s_inv); +int fdev_bscan(struct fpga_model *model, int y, int x, int type_idx, + int jtag_chain, int jtag_test); + int fdev_set_required_pins(struct fpga_model* model, int y, int x, int type, int type_idx); void fdev_print_required_pins(struct fpga_model* model, int y, int x, diff --git a/libs/parts.h b/libs/parts.h index 86ca214..c939202 100644 --- a/libs/parts.h +++ b/libs/parts.h @@ -450,3 +450,11 @@ void xc6_lut_bitmap(int lut_pos, int (*map)[64], int num_bits); #define XC6_TYPE2_GCLK_REG_SW 2 // bit 2 in 1st word #define XC6_CENTER_GCLK_MINOR 25 + +// +// bscan +// + +#define XC6_BSCAN_MINOR 22 +#define XC6_BSCAN_WORD 1 +#define XC6_BSCAN_TEST_PIN 4