finished basic bscan support
This commit is contained in:
parent
ba826ee297
commit
785d809538
2
README
2
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
|
||||
|
|
21
autotest.c
21
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)
|
||||
|
|
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -848,17 +849,30 @@ int fdev_bufgmux(struct fpga_model* model, int y, int x,
|
|||
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user