added 2 switch and conn helper functions
This commit is contained in:
parent
d36a3fa6a3
commit
3be3d504d2
75
autotest.c
75
autotest.c
|
@ -104,9 +104,12 @@ fail:
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
struct fpga_model model;
|
||||
struct fpga_device* dev;
|
||||
int iob_y, iob_x, iob_idx, rc;
|
||||
struct fpga_device* P46_dev, *P48_dev, *logic_dev;
|
||||
int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, i, j, sw_idx, rc;
|
||||
const char* str;
|
||||
struct test_state tstate;
|
||||
const char* conn_to_str;
|
||||
int conn_idx, conn_to_y, conn_to_x;
|
||||
|
||||
printf("\n");
|
||||
printf("O fpgatools automatic test suite. Be welcome and be "
|
||||
|
@ -132,44 +135,58 @@ int main(int argc, char** argv)
|
|||
if (rc) FAIL();
|
||||
|
||||
// configure P46
|
||||
rc = fpga_find_iob(&model, "P46", &iob_y, &iob_x, &iob_idx);
|
||||
rc = fpga_find_iob(&model, "P46", &P46_y, &P46_x, &P46_idx);
|
||||
if (rc) FAIL();
|
||||
dev = fpga_dev(&model, iob_y, iob_x, DEV_IOB, iob_idx);
|
||||
if (!dev) { rc = -1; FAIL(); }
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.istandard, IO_LVCMOS33);
|
||||
dev->iob.bypass_mux = BYPASS_MUX_I;
|
||||
dev->iob.I_mux = IMUX_I;
|
||||
P46_dev = fpga_dev(&model, P46_y, P46_x, DEV_IOB, P46_idx);
|
||||
if (!P46_dev) { rc = -1; FAIL(); }
|
||||
P46_dev->instantiated = 1;
|
||||
strcpy(P46_dev->iob.istandard, IO_LVCMOS33);
|
||||
P46_dev->iob.bypass_mux = BYPASS_MUX_I;
|
||||
P46_dev->iob.I_mux = IMUX_I;
|
||||
|
||||
// configure P48
|
||||
rc = fpga_find_iob(&model, "P48", &iob_y, &iob_x, &iob_idx);
|
||||
rc = fpga_find_iob(&model, "P48", &P48_y, &P48_x, &P48_idx);
|
||||
if (rc) FAIL();
|
||||
dev = fpga_dev(&model, iob_y, iob_x, DEV_IOB, iob_idx);
|
||||
if (!dev) { rc = -1; FAIL(); }
|
||||
dev->instantiated = 1;
|
||||
strcpy(dev->iob.ostandard, IO_LVCMOS33);
|
||||
dev->iob.drive_strength = 12;
|
||||
dev->iob.O_used = 1;
|
||||
dev->iob.slew = SLEW_SLOW;
|
||||
dev->iob.suspend = SUSP_3STATE;
|
||||
|
||||
rc = diff_printf(&tstate);
|
||||
if (rc) goto fail;
|
||||
P48_dev = fpga_dev(&model, P48_y, P48_x, DEV_IOB, P48_idx);
|
||||
if (!P48_dev) { rc = -1; FAIL(); }
|
||||
P48_dev->instantiated = 1;
|
||||
strcpy(P48_dev->iob.ostandard, IO_LVCMOS33);
|
||||
P48_dev->iob.drive_strength = 12;
|
||||
P48_dev->iob.O_used = 1;
|
||||
P48_dev->iob.slew = SLEW_SLOW;
|
||||
P48_dev->iob.suspend = SUSP_3STATE;
|
||||
|
||||
// configure logic
|
||||
dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, /*LOGIC_X*/ 1);
|
||||
if (!dev) { rc = -1; FAIL(); }
|
||||
dev->instantiated = 1;
|
||||
dev->logic.D_used = 1;
|
||||
rc = fpga_set_lut(&model, dev, D6_LUT, "A3", ZTERM);
|
||||
logic_dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, /*LOGIC_X*/ 1);
|
||||
if (!logic_dev) { rc = -1; FAIL(); }
|
||||
logic_dev->instantiated = 1;
|
||||
logic_dev->logic.D_used = 1;
|
||||
rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM);
|
||||
if (rc) FAIL();
|
||||
|
||||
#if 0
|
||||
rc = diff_printf(&tstate);
|
||||
if (rc) goto fail;
|
||||
#endif
|
||||
|
||||
// todo: start routing, step by step
|
||||
// todo: after each step, printf floorplan diff (test_diff.sh)
|
||||
// todo: popen/fork/pipe
|
||||
printf("P46 I pinw %s\n", P46_dev->iob.pinw_out_I);
|
||||
for (i = 0;; i++) {
|
||||
sw_idx = fpga_switch_dest(&model, P46_y, P46_x, P46_dev->iob.pinw_out_I, i);
|
||||
if (sw_idx == NO_SWITCH)
|
||||
break;
|
||||
str = fpga_switch_to(&model, P46_y, P46_x, sw_idx, /*bidir*/ 0);
|
||||
printf(" from %s to %s\n", P46_dev->iob.pinw_out_I, str);
|
||||
for (j = 0;; j++) {
|
||||
conn_idx = fpga_conn_dest(&model, P46_y, P46_x, str, j);
|
||||
if (conn_idx == NO_CONN)
|
||||
break;
|
||||
conn_to_str = fpga_conn_to(&model, P46_y, P46_x,
|
||||
conn_idx, &conn_to_y, &conn_to_x);
|
||||
printf(" %s goes to y%02i x%02i %s\n",
|
||||
str, conn_to_y, conn_to_x, conn_to_str);
|
||||
}
|
||||
}
|
||||
printf("P48 O pinw %s\n", P48_dev->iob.pinw_in_O);
|
||||
|
||||
printf("\n");
|
||||
printf("O Test suite completed.\n");
|
||||
|
|
168
control.c
168
control.c
|
@ -16,32 +16,32 @@ struct iob_site
|
|||
|
||||
static const struct iob_site xc6slx9_iob_top[] =
|
||||
{
|
||||
{ 5, {"P144", "P143", "P141", "P142"}},
|
||||
{ 7, {"P140", "P139", "P137", "P138"}},
|
||||
{12, {"UNB9", "UNB10", "UNB12", "UNB11"}},
|
||||
{14, {"UNB13", "UNB14", "UNB16", "UNB15"}},
|
||||
{19, {"UNB17", "UNB18", "UNB20", "UNB19"}},
|
||||
{21, {"P134", "P133", "P131", "P132"}},
|
||||
{25, {"P127", "P126", "P123", "P124"}},
|
||||
{29, {"UNB29", "UNB30", "UNB32", "UNB31"}},
|
||||
{31, {"UNB33", "UNB34", "P120", "P121"}},
|
||||
{36, {"P119", "P118", "P116", "P117"}},
|
||||
{38, {"P115", "P114", "P111", "P112"}},
|
||||
{ 5, {"P144", "P143", "P142", "P141"}},
|
||||
{ 7, {"P140", "P139", "P138", "P137"}},
|
||||
{12, {"UNB9", "UNB10", "UNB11", "UNB12"}},
|
||||
{14, {"UNB13", "UNB14", "UNB15", "UNB16"}},
|
||||
{19, {"UNB17", "UNB18", "UNB19", "UNB20"}},
|
||||
{21, {"P134", "P133", "P132", "P131"}},
|
||||
{25, {"P127", "P126", "P124", "P123"}},
|
||||
{29, {"UNB29", "UNB30", "UNB31", "UNB32"}},
|
||||
{31, {"UNB33", "UNB34", "P121", "P120"}},
|
||||
{36, {"P119", "P118", "P117", "P116"}},
|
||||
{38, {"P115", "P114", "P112", "P111"}},
|
||||
};
|
||||
|
||||
static const struct iob_site xc6slx9_iob_bottom[] =
|
||||
{
|
||||
{ 5, {"P38", "P39", "P41", "P40"}},
|
||||
{ 7, {"UNB140", "UNB139", "P44", "P43"}},
|
||||
{12, {"P45", "P46", "P48", "P47"}},
|
||||
{14, {"UNB132", "UNB131", "UNB129", "UNB130"}},
|
||||
{19, {"UNB128", "UNB127", "UNB125", "UNB126"}},
|
||||
{21, {"UNB124", "UNB123", "P51", "P50"}},
|
||||
{25, {"P55", "P56", "UNB117", "UNB118"}},
|
||||
{29, {"UNB116", "UNB115", "UNB113", "UNB114"}},
|
||||
{31, {"P57", "P58", "P60", "P59"}},
|
||||
{36, {"P61", "P62", "P65", "P64"}},
|
||||
{38, {"P66", "P67", "P70", "P69"}},
|
||||
{ 5, {"P39", "P38", "P40", "P41"}},
|
||||
{ 7, {"UNB139", "UNB140", "P43", "P44"}},
|
||||
{12, {"P46", "P45", "P47", "P48"}},
|
||||
{14, {"UNB131", "UNB132", "UNB130", "UNB129"}},
|
||||
{19, {"UNB127", "UNB128", "UNB126", "UNB125"}},
|
||||
{21, {"UNB123", "UNB124", "P50", "P51"}},
|
||||
{25, {"P56", "P55", "UNB118", "UNB117"}},
|
||||
{29, {"UNB115", "UNB116", "UNB114", "UNB113"}},
|
||||
{31, {"P58", "P57", "P59", "P60"}},
|
||||
{36, {"P62", "P61", "P64", "P65"}},
|
||||
{38, {"P67", "P66", "P69", "P70"}},
|
||||
};
|
||||
|
||||
static const struct iob_site xc6slx9_iob_left[] =
|
||||
|
@ -261,3 +261,127 @@ int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev,
|
|||
(*ptr)[lut_len] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fpga_conn_dest(struct fpga_model* model, int y, int x,
|
||||
const char* name, int dest_idx)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
int i, rc, connpt_i, num_dests, conn_point_dests_o;
|
||||
|
||||
rc = strarray_find(&model->str, name, &connpt_i);
|
||||
if (rc) FAIL();
|
||||
tile = YX_TILE(model, y, x);
|
||||
for (i = 0; i < tile->num_conn_point_names; i++) {
|
||||
if (tile->conn_point_names[i*2+1] == connpt_i)
|
||||
break;
|
||||
}
|
||||
if (i >= tile->num_conn_point_names)
|
||||
FAIL();
|
||||
|
||||
conn_point_dests_o = tile->conn_point_names[i*2];
|
||||
if (i < tile->num_conn_point_names-1)
|
||||
num_dests = tile->conn_point_names[(i+1)*2] - conn_point_dests_o;
|
||||
else
|
||||
num_dests = tile->num_conn_point_dests - conn_point_dests_o;
|
||||
if (dest_idx >= num_dests)
|
||||
return NO_CONN;
|
||||
return conn_point_dests_o + dest_idx;
|
||||
fail:
|
||||
return NO_CONN;
|
||||
}
|
||||
|
||||
#define NUM_CONN_DEST_BUFS 16
|
||||
#define CONN_DEST_BUF_SIZE 128
|
||||
|
||||
const char* fpga_conn_to(struct fpga_model* model, int y, int x,
|
||||
int connpt_dest_idx, int* dest_y, int* dest_x)
|
||||
{
|
||||
static char conn_dest_buf[NUM_CONN_DEST_BUFS][CONN_DEST_BUF_SIZE];
|
||||
static int last_buf = 0;
|
||||
|
||||
struct fpga_tile* tile;
|
||||
const char* hash_str;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
if (connpt_dest_idx < 0
|
||||
|| connpt_dest_idx >= tile->num_conn_point_dests) {
|
||||
HERE();
|
||||
return 0;
|
||||
}
|
||||
*dest_x = tile->conn_point_dests[connpt_dest_idx*3];
|
||||
*dest_y = tile->conn_point_dests[connpt_dest_idx*3+1];
|
||||
|
||||
hash_str = strarray_lookup(&model->str,
|
||||
tile->conn_point_dests[connpt_dest_idx*3+2]);
|
||||
if (!hash_str || (strlen(hash_str) >= CONN_DEST_BUF_SIZE)) {
|
||||
HERE();
|
||||
return 0;
|
||||
}
|
||||
last_buf = (last_buf+1)%NUM_CONN_DEST_BUFS;
|
||||
strcpy(conn_dest_buf[last_buf], hash_str);
|
||||
|
||||
return conn_dest_buf[last_buf];
|
||||
}
|
||||
|
||||
int fpga_switch_dest(struct fpga_model* model, int y, int x,
|
||||
const char* name, int dest_idx)
|
||||
{
|
||||
struct fpga_tile* tile;
|
||||
int rc, i, connpt_o, from_name_i, dest_idx_counter;
|
||||
|
||||
rc = strarray_find(&model->str, name, &from_name_i);
|
||||
if (rc) FAIL();
|
||||
|
||||
// counts how many switches from the same source (name)
|
||||
// we have already encountered - to find the dest_idx'th
|
||||
// entry in that series
|
||||
dest_idx_counter = 0;
|
||||
tile = YX_TILE(model, y, x);
|
||||
for (i = 0; i < tile->num_switches; i++) {
|
||||
connpt_o = SWITCH_FROM(tile->switches[i]);
|
||||
if (tile->conn_point_names[connpt_o*2+1] == from_name_i) {
|
||||
if (dest_idx_counter >= dest_idx)
|
||||
break;
|
||||
dest_idx_counter++;
|
||||
}
|
||||
}
|
||||
if (i >= tile->num_switches)
|
||||
return NO_SWITCH;
|
||||
if (dest_idx_counter > dest_idx) FAIL();
|
||||
return i;
|
||||
fail:
|
||||
return NO_SWITCH;
|
||||
}
|
||||
|
||||
#define NUM_SWITCH_TO_BUFS 16
|
||||
#define SWITCH_TO_BUF_SIZE 128
|
||||
|
||||
const char* fpga_switch_to(struct fpga_model* model, int y, int x,
|
||||
int swidx, int* is_bidir)
|
||||
{
|
||||
// We have a little local ringbuffer to make passing
|
||||
// around pointers with unknown lifetime and possible
|
||||
// overlap with writing functions more stable.
|
||||
static char switch_to_buf[NUM_SWITCH_TO_BUFS][SWITCH_TO_BUF_SIZE];
|
||||
static int last_buf = 0;
|
||||
|
||||
struct fpga_tile* tile;
|
||||
const char* hash_str;
|
||||
int connpt_o, str_i;
|
||||
|
||||
tile = YX_TILE(model, y, x);
|
||||
if (is_bidir)
|
||||
*is_bidir = (tile->switches[swidx] & SWITCH_BIDIRECTIONAL) != 0;
|
||||
|
||||
connpt_o = SWITCH_TO(tile->switches[swidx]);
|
||||
str_i = tile->conn_point_names[connpt_o*2+1];
|
||||
hash_str = strarray_lookup(&model->str, str_i);
|
||||
if (!hash_str || (strlen(hash_str) >= SWITCH_TO_BUF_SIZE)) {
|
||||
HERE();
|
||||
return 0;
|
||||
}
|
||||
last_buf = (last_buf+1)%NUM_SWITCH_TO_BUFS;
|
||||
strcpy(switch_to_buf[last_buf], hash_str);
|
||||
|
||||
return switch_to_buf[last_buf];
|
||||
}
|
||||
|
|
12
control.h
12
control.h
|
@ -30,3 +30,15 @@ enum { A6_LUT, B6_LUT, C6_LUT, D6_LUT };
|
|||
// lut_len can be -1 (ZTERM)
|
||||
int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev,
|
||||
int which_lut, const char* lut_str, int lut_len);
|
||||
|
||||
// returns a connpt dest index, or -1 (NO_CONN) if no connection was found
|
||||
int fpga_conn_dest(struct fpga_model* model, int y, int x,
|
||||
const char* name, int dest_idx);
|
||||
const char* fpga_conn_to(struct fpga_model* model, int y, int x,
|
||||
int connpt_dest_idx, int* dest_y, int* dest_x);
|
||||
|
||||
// returns a switch index, or -1 (NO_SWITCH) if no switch was found
|
||||
int fpga_switch_dest(struct fpga_model* model, int y, int x,
|
||||
const char* name, int dest_idx);
|
||||
const char* fpga_switch_to(struct fpga_model* model, int y, int x,
|
||||
int swidx, int* is_bidir);
|
||||
|
|
16
model.h
16
model.h
|
@ -365,9 +365,14 @@ struct fpga_device
|
|||
};
|
||||
};
|
||||
|
||||
#define SWITCH_ON 0x80000000
|
||||
#define SWITCH_BIDIRECTIONAL 0x40000000
|
||||
#define SWITCH_MAX_CONNPT_O 0x7FFF // 15 bits
|
||||
#define SWITCH_ON 0x80000000
|
||||
#define SWITCH_BIDIRECTIONAL 0x40000000
|
||||
#define SWITCH_MAX_CONNPT_O 0x7FFF // 15 bits
|
||||
#define SWITCH_FROM(u32) (((u32) >> 15) & SWITCH_MAX_CONNPT_O)
|
||||
#define SWITCH_TO(u32) ((u32) & SWITCH_MAX_CONNPT_O)
|
||||
|
||||
#define NO_SWITCH -1
|
||||
#define NO_CONN -1
|
||||
|
||||
struct fpga_tile
|
||||
{
|
||||
|
@ -382,6 +387,7 @@ struct fpga_tile
|
|||
// 2*16 bit per entry
|
||||
// - index into conn_point_dests (not multiplied by 3) (16bit)
|
||||
// - hashed string array index (16 bit)
|
||||
// each conn point name exists only once in the array
|
||||
int num_conn_point_names; // conn_point_names is 2*num_conn_point_names 16-bit words
|
||||
uint16_t* conn_point_names; // num_conn_point_names*2 16-bit-words: 16(conn)-16(str)
|
||||
|
||||
|
@ -396,8 +402,8 @@ struct fpga_tile
|
|||
// expect up to 4k switches per tile
|
||||
// 32bit: 31 off: no connection on: connected
|
||||
// 30 off: unidirectional on: bidirectional
|
||||
// 29:15 from, index into conn_point_names
|
||||
// 14:0 to, index into conn_point_names
|
||||
// 29:15 from, index into conn_point_names (not yet *2)
|
||||
// 14:0 to, index into conn_point_names (not yet *2)
|
||||
int num_switches;
|
||||
uint32_t* switches;
|
||||
};
|
||||
|
|
|
@ -63,12 +63,12 @@ static int init_iob(struct fpga_model* model, int y, int x,
|
|||
if (rc) FAIL();
|
||||
snprintf(tile->devs[idx].iob.pinw_in_T,
|
||||
sizeof(tile->devs[idx].iob.pinw_in_T),
|
||||
"%s_IBUF%i_PINW", prefix, type_idx);
|
||||
"%s_T%i_PINW", prefix, type_idx);
|
||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_in_T);
|
||||
if (rc) FAIL();
|
||||
snprintf(tile->devs[idx].iob.pinw_out_I,
|
||||
sizeof(tile->devs[idx].iob.pinw_out_I),
|
||||
"%s_T%i_PINW", prefix, type_idx);
|
||||
"%s_IBUF%i_PINW", prefix, type_idx);
|
||||
rc = add_connpt_name(model, y, x, tile->devs[idx].iob.pinw_out_I);
|
||||
if (rc) FAIL();
|
||||
snprintf(tile->devs[idx].iob.pinw_out_PADOUT,
|
||||
|
@ -344,8 +344,8 @@ int init_devices(struct fpga_model* model)
|
|||
y = TOP_OUTER_ROW;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBS))) goto fail;
|
||||
|
||||
y = model->y_height-BOT_OUTER_ROW;
|
||||
if ((rc = add_dev(model, y, x, DEV_IOB, IOBM))) goto fail;
|
||||
|
|
|
@ -38,10 +38,8 @@ int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* column
|
|||
rc = init_conns(model);
|
||||
if (rc) return rc;
|
||||
|
||||
#if 0
|
||||
rc = init_switches(model);
|
||||
if (rc) return rc;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -34,8 +34,10 @@ int init_switches(struct fpga_model* model)
|
|||
rc = init_io_switches(model);
|
||||
if (rc) goto xout;
|
||||
|
||||
#if 0
|
||||
rc = init_routing_switches(model);
|
||||
if (rc) goto xout;
|
||||
#endif
|
||||
return 0;
|
||||
xout:
|
||||
return rc;
|
||||
|
|
Loading…
Reference in New Issue
Block a user