switches, but hit a dead end, have to work on nets...
This commit is contained in:
parent
2b80d283f4
commit
2826effa01
51
control.c
51
control.c
|
@ -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; }
|
||||
|
||||
*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;
|
||||
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];
|
||||
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;
|
||||
}
|
||||
|
|
11
control.h
11
control.h
|
@ -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);
|
||||
|
|
234
floorplan.c
234
floorplan.c
|
@ -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;
|
||||
}
|
||||
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 == 2
|
||||
&& !str_cmp(&line[beg], 2, "sw", 2)) {
|
||||
read_sw_line(model, line, end);
|
||||
}
|
||||
if (end-beg == 3
|
||||
&& !str_cmp(&line[beg], 3, "dev", 3)) {
|
||||
read_dev_line(model, line, end);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user