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)
|
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
|
||||||
|
|
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)
|
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)
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -3042,7 +3118,7 @@ static int write_logic(struct fpga_bits* bits, struct fpga_model* model)
|
||||||
RC_RETURN(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;
|
int i;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,25 +841,38 @@ fail:
|
||||||
return rc;
|
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)
|
int type_idx, int clk, int disable_attr, int s_inv)
|
||||||
{
|
{
|
||||||
struct fpga_device* dev;
|
struct fpga_device *dev;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user