finished basic bscan support

This commit is contained in:
Wolfgang Spraul 2013-01-26 23:25:16 -05:00
parent ba826ee297
commit 785d809538
6 changed files with 143 additions and 22 deletions

2
README
View File

@ -63,8 +63,8 @@ Design Principles
TODO (as of January, 2013) TODO (as of January, 2013)
short-term (1 month): short-term (1 month):
* support distributed and block memory
* example: counter (including clock, jtag) * example: counter (including clock, jtag)
* support xc6slx9-ftg256
mid-term (6 months): mid-term (6 months):
* example: j1 soc * example: j1 soc

View File

@ -1795,8 +1795,27 @@ static int test_dcm_config(struct test_state* tstate)
static int test_bscan_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; return 0;
fail:
return rc;
} }
static int test_clock_routing(struct test_state* tstate) static int test_clock_routing(struct test_state* tstate)

View File

@ -2217,6 +2217,80 @@ static void destruct_extract_state(struct extract_state *es)
es->yx_pos = 0; 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) int extract_model(struct fpga_model* model, struct fpga_bits* bits)
{ {
struct extract_state es; 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; } if (rc) { RC_SET(model, rc); goto out; }
rc = extract_logic(&es); rc = extract_logic(&es);
if (rc) { RC_SET(model, rc); goto out; } if (rc) { RC_SET(model, rc); goto out; }
rc = extract_bscan(&es);
if (rc) { RC_SET(model, rc); goto out; }
// turn switches into nets // turn switches into nets
if (model->nets) if (model->nets)
@ -3053,6 +3129,7 @@ int write_model(struct fpga_bits* bits, struct fpga_model* model)
write_switches(bits, model); write_switches(bits, model);
write_type2(bits, model); write_type2(bits, model);
write_logic(bits, model); write_logic(bits, model);
write_bscan(bits, model);
RC_RETURN(model); RC_RETURN(model);
} }

View File

@ -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, static void enum_x(struct fpga_model *model, enum fpgadev_type type,
int enum_i, int *y, int x, int *type_idx) 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; struct fpga_tile* tile;
type_count = 0; total_type_count = 0;
tile_type_count = 0;
for (_y = 0; _y < model->y_height; _y++) { for (_y = 0; _y < model->y_height; _y++) {
tile = YX_TILE(model, _y, x); tile = YX_TILE(model, _y, x);
total_type_count += tile_type_count;
tile_type_count = 0;
for (i = 0; i < tile->num_devs; i++) { for (i = 0; i < tile->num_devs; i++) {
if (tile->devs[i].type != type) if (tile->devs[i].type != type)
continue; continue;
if (type_count == enum_i) { if (total_type_count + tile_type_count == enum_i) {
*y = _y; *y = _y;
*type_idx = type_count; *type_idx = tile_type_count;
return; return;
} }
type_count++; tile_type_count++;
} }
} }
*y = -1; *y = -1;
@ -106,6 +109,7 @@ int fdev_enum(struct fpga_model* model, enum fpgadev_type type, int enum_i,
struct fpga_tile* tile; struct fpga_tile* tile;
int i, j, type_count; int i, j, type_count;
*y = -1;
RC_CHECK(model); RC_CHECK(model);
switch (type) { switch (type) {
case DEV_BUFGMUX: case DEV_BUFGMUX:
@ -123,7 +127,6 @@ int fdev_enum(struct fpga_model* model, enum fpgadev_type type, int enum_i,
} }
type_count++; type_count++;
} }
*y = -1;
RC_RETURN(model); RC_RETURN(model);
case DEV_BUFIO: { case DEV_BUFIO: {
int yx_pairs[] = { int yx_pairs[] = {
@ -147,22 +150,20 @@ int fdev_enum(struct fpga_model* model, enum fpgadev_type type, int enum_i,
type_count++; type_count++;
} }
} }
*y = -1;
RC_RETURN(model); RC_RETURN(model);
} }
case DEV_PLL: case DEV_PLL:
case DEV_DCM: case DEV_DCM:
enum_x(model, type, enum_i, y, model->center_x *x = model->center_x - CENTER_CMTPLL_O;
- CENTER_CMTPLL_O, type_idx); enum_x(model, type, enum_i, y, *x, type_idx);
RC_RETURN(model); RC_RETURN(model);
case DEV_BSCAN: case DEV_BSCAN:
enum_x(model, type, enum_i, y, model->x_width *x = model->x_width - RIGHT_IO_DEVS_O;
- RIGHT_IO_DEVS_O, type_idx); enum_x(model, type, enum_i, y, *x, type_idx);
RC_RETURN(model); RC_RETURN(model);
default: break; default: break;
} }
HERE(); HERE();
*y = -1;
RC_RETURN(model); RC_RETURN(model);
} }
@ -848,17 +849,30 @@ int fdev_bufgmux(struct fpga_model* model, int y, int x,
RC_CHECK(model); RC_CHECK(model);
dev = fdev_p(model, y, x, DEV_BUFGMUX, type_idx); dev = fdev_p(model, y, x, DEV_BUFGMUX, type_idx);
if (!dev) FAIL(EINVAL); RC_ASSERT(model, dev);
rc = reset_required_pins(dev); rc = reset_required_pins(dev);
if (rc) FAIL(rc); if (rc) RC_FAIL(model, rc);
dev->u.bufgmux.clk = clk; dev->u.bufgmux.clk = clk;
dev->u.bufgmux.disable_attr = disable_attr; dev->u.bufgmux.disable_attr = disable_attr;
dev->u.bufgmux.s_inv = s_inv; dev->u.bufgmux.s_inv = s_inv;
dev->instantiated = 1; dev->instantiated = 1;
return 0; RC_RETURN(model);
fail: }
return rc;
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) static void scan_lut_digits(const char* s, int* digits)

View File

@ -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 fdev_bufgmux(struct fpga_model* model, int y, int x,
int type_idx, int clk, int disable_attr, int s_inv); 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 fdev_set_required_pins(struct fpga_model* model, int y, int x, int type,
int type_idx); int type_idx);
void fdev_print_required_pins(struct fpga_model* model, int y, int x, void fdev_print_required_pins(struct fpga_model* model, int y, int x,

View File

@ -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_TYPE2_GCLK_REG_SW 2 // bit 2 in 1st word
#define XC6_CENTER_GCLK_MINOR 25 #define XC6_CENTER_GCLK_MINOR 25
//
// bscan
//
#define XC6_BSCAN_MINOR 22
#define XC6_BSCAN_WORD 1
#define XC6_BSCAN_TEST_PIN 4