switches, but hit a dead end, have to work on nets...

This commit is contained in:
Wolfgang Spraul 2012-08-24 10:39:21 +02:00
parent 2b80d283f4
commit 2826effa01
3 changed files with 204 additions and 92 deletions

View File

@ -263,10 +263,10 @@ int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev,
}
int fpga_connpt_find(struct fpga_model* model, int y, int x,
str16_t name_i, int* connpt_dests_o)
str16_t name_i, int* connpt_dests_o, int* num_dests)
{
struct fpga_tile* tile;
int i, num_dests;
int i;
tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_conn_point_names; i++) {
@ -275,15 +275,18 @@ int fpga_connpt_find(struct fpga_model* model, int y, int x,
}
if (i >= tile->num_conn_point_names)
{ HERE(); goto fail; }
if (num_dests) {
*num_dests = (i < tile->num_conn_point_names-1)
? tile->conn_point_names[(i+1)*2]
- tile->conn_point_names[i*2]
: tile->num_conn_point_dests
- tile->conn_point_names[i*2];
}
if (connpt_dests_o)
*connpt_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] - *connpt_dests_o;
else
num_dests = tile->num_conn_point_dests - *connpt_dests_o;
return num_dests;
return i;
fail:
return 0;
return NO_CONN;
}
void fpga_conn_dest(struct fpga_model* model, int y, int x,
@ -348,6 +351,28 @@ swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
return fpga_switch_search(model, y, x, last, /*search_beg*/ 0, from_to);
}
swidx_t fpga_switch_lookup(struct fpga_model* model, int y, int x,
str16_t from_str_i, str16_t to_str_i)
{
int from_connpt_o, to_connpt_o, i;
struct fpga_tile* tile;
from_connpt_o = fpga_connpt_find(model, y, x, from_str_i,
/*dests_o*/ 0, /*num_dests*/ 0);
to_connpt_o = fpga_connpt_find(model, y, x, to_str_i,
/*dests_o*/ 0, /*num_dests*/ 0);
if (from_connpt_o == NO_CONN || to_connpt_o == NO_CONN)
return NO_SWITCH;
tile = YX_TILE(model, y, x);
for (i = 0; i < tile->num_switches; i++) {
if (SW_FROM_I(tile->switches[i]) == from_connpt_o
&& SW_TO_I(tile->switches[i]) == to_connpt_o)
return i;
}
return NO_SWITCH;
}
#define NUM_CONNPT_BUFS 64
#define CONNPT_BUF_SIZE 128
@ -628,9 +653,9 @@ int fpga_switch_conns(struct sw_conns* conns)
if (end_of_chain_str == STRIDX_NO_ENTRY)
{ HERE(); goto internal_error; }
conns->dest_i = 0;
conns->num_dests = fpga_connpt_find(conns->model,
conns->y, conns->x, end_of_chain_str,
&conns->connpt_dest_start);
fpga_connpt_find(conns->model, conns->y, conns->x,
end_of_chain_str, &conns->connpt_dest_start,
&conns->num_dests);
if (conns->num_dests)
break;
}

View File

@ -31,11 +31,12 @@ enum { A6_LUT, B6_LUT, C6_LUT, D6_LUT };
int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev,
int which_lut, const char* lut_str, int lut_len);
// returns the number of outgoing connections for the
// connection point given with 'name', and the connection
// point's first dest offset in connpt_dests_o.
// Returns the connpt index or NO_CONN if the name was not
// found. connpt_dests_o and num_dests are optional and may
// return the offset into the connpt's destination array
// and number of elements there.
int fpga_connpt_find(struct fpga_model* model, int y, int x,
str16_t name_i, int* connpt_dests_o);
str16_t name_i, int* connpt_dests_o, int* num_dests);
void fpga_conn_dest(struct fpga_model* model, int y, int x,
int connpt_dest_idx, int* dest_y, int* dest_x, str16_t* str_i);
@ -56,6 +57,8 @@ swidx_t fpga_switch_next(struct fpga_model* model, int y, int x,
swidx_t last, int from_to);
swidx_t fpga_switch_backtofirst(struct fpga_model* model, int y, int x,
swidx_t last, int from_to);
swidx_t fpga_switch_lookup(struct fpga_model* model, int y, int x,
str16_t from_str_i, str16_t to_str_i);
const char* fpga_switch_str(struct fpga_model* model, int y, int x,
swidx_t swidx, int from_to);

View File

@ -673,6 +673,158 @@ static enum fpgadev_type to_type(const char* s, int len)
return DEV_NONE;
}
static int coord(const char* s, int start, int* end, int* y, int* x)
{
int y_beg, y_end, x_beg, x_end, rc;
next_word(s, start, &y_beg, &y_end);
next_word(s, y_end, &x_beg, &x_end);
if (y_end < y_beg+2 || x_end < x_beg+2
|| s[y_beg] != 'y' || s[x_beg] != 'x'
|| !all_digits(&s[y_beg+1], y_end-y_beg-1)
|| !all_digits(&s[x_beg+1], x_end-x_beg-1)) {
FAIL(EINVAL);
}
*y = to_i(&s[y_beg+1], y_end-y_beg-1);
*x = to_i(&s[x_beg+1], x_end-x_beg-1);
*end = x_end;
return 0;
fail:
return rc;
}
static void read_sw_line(struct fpga_model* model, const char* line, int start)
{
int coord_end, y_coord, x_coord;
int from_beg, from_end, from_str_i;
int direction_beg, direction_end, is_bidir;
int to_beg, to_end, to_str_i;
int on_beg, on_end, is_on;
swidx_t sw_idx;
int sw_is_bidir;
char buf[1024];
if (coord(line, start, &coord_end, &y_coord, &x_coord))
return;
next_word(line, coord_end, &from_beg, &from_end);
next_word(line, from_end, &direction_beg, &direction_end);
next_word(line, direction_end, &to_beg, &to_end);
next_word(line, to_end, &on_beg, &on_end);
if (from_end <= from_beg || direction_end <= direction_beg
|| to_end <= to_beg) {
HERE();
return;
}
memcpy(buf, &line[from_beg], from_end-from_beg);
buf[from_end-from_beg] = 0;
if (strarray_find(&model->str, buf, &from_str_i)
|| from_str_i == STRIDX_NO_ENTRY) {
HERE();
return;
}
if (!str_cmp(&line[direction_beg], direction_end-direction_beg,
"->", 2))
is_bidir = 0;
else if (!str_cmp(&line[direction_beg], direction_end-direction_beg,
"<->", 3))
is_bidir = 1;
else {
HERE();
return;
}
memcpy(buf, &line[to_beg], to_end-to_beg);
buf[to_end-to_beg] = 0;
if (strarray_find(&model->str, buf, &to_str_i)
|| to_str_i == STRIDX_NO_ENTRY) {
HERE();
return;
}
if (on_end == on_beg)
is_on = 0;
else if (!str_cmp(&line[on_beg], on_end-on_beg, "on", 2))
is_on = 1;
else {
HERE();
return;
}
sw_idx = fpga_switch_lookup(model, y_coord, x_coord, from_str_i, to_str_i);
if (sw_idx == NO_SWITCH) {
HERE();
return;
}
sw_is_bidir = fpga_switch_is_bidir(model, y_coord, x_coord, sw_idx);
if ((is_bidir && !sw_is_bidir)
|| (!is_bidir && sw_is_bidir)) {
HERE();
return;
}
if (fpga_switch_is_enabled(model, y_coord, x_coord, sw_idx))
HERE();
if (is_on)
fpga_switch_enable(model, y_coord, x_coord, sw_idx);
}
static void read_dev_line(struct fpga_model* model, const char* line, int start)
{
int coord_end, y_coord, x_coord;
int type_beg, type_end, idx_beg, idx_end;
enum fpgadev_type dev_type;
int dev_idx, words_consumed;
struct fpga_device* dev_ptr;
int next_beg, next_end, second_beg, second_end;
if (coord(line, start, &coord_end, &y_coord, &x_coord))
return;
next_word(line, coord_end, &type_beg, &type_end);
next_word(line, type_end, &idx_beg, &idx_end);
if (type_end == type_beg || idx_end == idx_beg
|| !all_digits(&line[idx_beg], idx_end-idx_beg)) {
fprintf(stderr, "error %i: %s", __LINE__, line);
return;
}
dev_type = to_type(&line[type_beg], type_end-type_beg);
dev_idx = to_i(&line[idx_beg], idx_end-idx_beg);
dev_ptr = fpga_dev(model, y_coord, x_coord, dev_type, dev_idx);
if (!dev_ptr) {
fprintf(stderr, "error %i: %s", __LINE__, line);
return;
}
next_end = idx_end;
while (next_word(line, next_end, &next_beg, &next_end),
next_end > next_beg) {
next_word(line, next_end, &second_beg, &second_end);
switch (dev_type) {
case DEV_IOB:
words_consumed = read_IOB_attr(model, dev_ptr,
&line[next_beg], next_end-next_beg,
&line[second_beg],
second_end-second_beg);
break;
case DEV_LOGIC:
words_consumed = read_LOGIC_attr(model, dev_ptr,
&line[next_beg], next_end-next_beg,
&line[second_beg],
second_end-second_beg);
break;
default:
fprintf(stderr, "error %i: %s", __LINE__, line);
return;
}
if (!words_consumed)
fprintf(stderr, "error %i w1 %.*s w2 %.*s: %s",
__LINE__, next_end-next_beg, &line[next_beg],
second_end-second_beg, &line[second_beg], line);
else if (words_consumed == 2)
next_end = second_end;
}
}
int read_floorplan(struct fpga_model* model, FILE* f)
{
char line[1024];
@ -682,81 +834,13 @@ int read_floorplan(struct fpga_model* model, FILE* f)
next_word(line, 0, &beg, &end);
if (end == beg) continue;
if (!str_cmp(&line[beg], end-beg, "dev", 3)) {
int y_beg, y_end, x_beg, x_end;
int y_coord, x_coord;
int type_beg, type_end, idx_beg, idx_end;
enum fpgadev_type dev_type;
int dev_idx, words_consumed;
struct fpga_device* dev_ptr;
int next_beg, next_end, second_beg, second_end;
next_word(line, end, &y_beg, &y_end);
next_word(line, y_end, &x_beg, &x_end);
if (y_end < y_beg+2 || x_end < x_beg+2
|| line[y_beg] != 'y' || line[x_beg] != 'x'
|| !all_digits(&line[y_beg+1], y_end-y_beg-1)
|| !all_digits(&line[x_beg+1], x_end-x_beg-1)) {
fprintf(stderr, "error %i: %s", __LINE__, line);
continue;
if (end-beg == 2
&& !str_cmp(&line[beg], 2, "sw", 2)) {
read_sw_line(model, line, end);
}
y_coord = to_i(&line[y_beg+1], y_end-y_beg-1);
x_coord = to_i(&line[x_beg+1], x_end-x_beg-1);
next_word(line, x_end, &type_beg, &type_end);
next_word(line, type_end, &idx_beg, &idx_end);
if (type_end == type_beg || idx_end == idx_beg
|| !all_digits(&line[idx_beg], idx_end-idx_beg)) {
fprintf(stderr, "error %i: %s", __LINE__, line);
continue;
}
dev_type = to_type(&line[type_beg], type_end-type_beg);
dev_idx = to_i(&line[idx_beg], idx_end-idx_beg);
dev_ptr = fpga_dev(model, y_coord, x_coord, dev_type, dev_idx);
if (!dev_ptr) {
fprintf(stderr, "error %i: %s", __LINE__, line);
continue;
}
next_end = idx_end;
while (next_word(line, next_end, &next_beg, &next_end),
next_end > next_beg) {
next_word(line, next_end, &second_beg, &second_end);
switch (dev_type) {
case DEV_IOB:
words_consumed = read_IOB_attr(
model, dev_ptr,
&line[next_beg],
next_end-next_beg,
&line[second_beg],
second_end-second_beg);
break;
case DEV_LOGIC:
words_consumed = read_LOGIC_attr(
model, dev_ptr,
&line[next_beg],
next_end-next_beg,
&line[second_beg],
second_end-second_beg);
break;
default:
fprintf(stderr, "error %i: %s",
__LINE__, line);
goto next_line;
}
if (!words_consumed)
fprintf(stderr,
"error %i w1 %.*s w2 %.*s: %s",
__LINE__, next_end-next_beg,
&line[next_beg],
second_end-second_beg,
&line[second_beg],
line);
else if (words_consumed == 2)
next_end = second_end;
}
next_line: ;
if (end-beg == 3
&& !str_cmp(&line[beg], 3, "dev", 3)) {
read_dev_line(model, line, end);
}
}
return 0;