diff --git a/control.c b/control.c index 4f73023..d1f2666 100644 --- a/control.c +++ b/control.c @@ -200,6 +200,27 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x, return 0; } +static const char* dev_str[] = FPGA_DEV_STR; + +const char* fpgadev_str(enum fpgadev_type type) +{ + if (type < 0 || type >= sizeof(dev_str)/sizeof(*dev_str)) + { HERE(); return 0; } + return dev_str[type]; +} + +enum fpgadev_type fpgadev_str2type(const char* str, int len) +{ + int i; + for (i = 0; i < sizeof(dev_str)/sizeof(*dev_str); i++) { + if (dev_str[i] + && strlen(dev_str[i]) == len + && !str_cmp(dev_str[i], len, str, len)) + return i; + } + return DEV_NONE; +} + dev_idx_t fpga_dev_idx(struct fpga_model* model, int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx) { @@ -234,6 +255,55 @@ dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x, return type_count; } +static const char* iob_pinw_str[] = IOB_PINW_STR; +static const char* logic_pinw_str[] = LOGIC_PINW_STR; + +pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str, int len) +{ + int i; + + if (devtype == DEV_IOB) { + for (i = 0; i < sizeof(iob_pinw_str)/sizeof(*iob_pinw_str); i++) { + if (strlen(iob_pinw_str[i]) == len + && !str_cmp(iob_pinw_str[i], len, str, len)) + return i; + } + HERE(); + return PINW_NO_IDX; + } + if (devtype == DEV_LOGIC) { + for (i = 0; i < sizeof(logic_pinw_str)/sizeof(*logic_pinw_str); i++) { + if (strlen(logic_pinw_str[i]) == len + && !str_cmp(logic_pinw_str[i], len, str, len)) + return i; + } + HERE(); + return PINW_NO_IDX; + } + HERE(); + return PINW_NO_IDX; +} + +const char* fpgadev_pinw_idx2str(int devtype, pinw_idx_t idx) +{ + if (devtype == DEV_IOB) { + if (idx < 0 || idx >= sizeof(iob_pinw_str)/sizeof(*iob_pinw_str)) { + HERE(); + return 0; + } + return iob_pinw_str[idx]; + } + if (devtype == DEV_LOGIC) { + if (idx < 0 || idx >= sizeof(logic_pinw_str)/sizeof(*logic_pinw_str)) { + HERE(); + return 0; + } + return logic_pinw_str[idx]; + } + HERE(); + return 0; +} + #define MAX_LUT_LEN 512 int fpga_set_lut(struct fpga_model* model, struct fpga_device* dev, @@ -774,28 +844,42 @@ int fpga_switch_to_yx(struct switch_to_yx* p) #define NET_ALLOC_INCREMENT 64 -int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx) +static int fpga_net_useidx(struct fpga_model* model, net_idx_t new_idx) { int rc; - if (!(model->num_nets % NET_ALLOC_INCREMENT)) { + if (new_idx <= NO_NET) FAIL(EINVAL); + if ((new_idx-1) < model->num_nets) + return 0; + if ((new_idx-1) >= (model->num_nets+NET_ALLOC_INCREMENT-1) + /NET_ALLOC_INCREMENT*NET_ALLOC_INCREMENT) { void* new_ptr; int new_len; - new_len = (model->num_nets+NET_ALLOC_INCREMENT) - *sizeof(*model->nets); + new_len = ((new_idx-1)/NET_ALLOC_INCREMENT+1) + *NET_ALLOC_INCREMENT*sizeof(*model->nets); new_ptr = realloc(model->nets, new_len); if (!new_ptr) FAIL(ENOMEM); model->nets = new_ptr; } - model->nets[model->num_nets].len = 0; + model->nets[(new_idx-1)].len = 0; model->num_nets++; - *new_idx = model->num_nets; return 0; fail: return rc; } +int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx) +{ + int rc; + + rc = fpga_net_useidx(model, model->num_nets+1); + if (rc) return rc; + *new_idx = model->num_nets+1; + model->num_nets++; + return 0; +} + int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next) { int i; @@ -828,6 +912,9 @@ int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i, struct fpga_net* net; int rc; + rc = fpga_net_useidx(model, net_i); + if (rc) FAIL(rc); + net = &model->nets[net_i-1]; if (net->len >= MAX_NET_LEN) FAIL(EINVAL); @@ -847,6 +934,9 @@ int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, struct fpga_net* net; int i, rc; + rc = fpga_net_useidx(model, net_i); + if (rc) FAIL(rc); + net = &model->nets[net_i-1]; if (net->len+set->len > MAX_NET_LEN) FAIL(EINVAL); diff --git a/control.h b/control.h index 1d163ed..c8eda95 100644 --- a/control.h +++ b/control.h @@ -17,7 +17,11 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x, // 2. The index of the device within devices of the same type in the tile. // +const char* fpgadev_str(enum fpgadev_type type); +enum fpgadev_type fpgadev_str2type(const char* str, int len); + // Looks up a device index based on the type index. +// returns NO_DEV (-1) if not found dev_idx_t fpga_dev_idx(struct fpga_model* model, int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx); @@ -26,6 +30,11 @@ dev_idx_t fpga_dev_idx(struct fpga_model* model, dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x, dev_idx_t dev_idx); +#define PINW_NO_IDX -1 +pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str, int len); +// returns 0 when idx not found for the given devtype +const char* fpgadev_pinw_idx2str(int devtype, pinw_idx_t idx); + 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, diff --git a/floorplan.c b/floorplan.c index 2bcb5e9..3945fd7 100644 --- a/floorplan.c +++ b/floorplan.c @@ -636,78 +636,124 @@ fail: return rc; } -static void read_sw_line(struct fpga_model* model, const char* line, int start) +static void read_net_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; + int net_idx_beg, net_idx_end, el_type_beg, el_type_end; + int dev_str_beg, dev_str_end, dev_type_idx_str_beg, dev_type_idx_str_end; + int pin_str_beg, pin_str_end, pin_name_beg, pin_name_end; + enum fpgadev_type dev_type; char buf[1024]; + net_idx_t net_idx; + dev_idx_t dev_idx; + pinw_idx_t pinw_idx; + int sw_is_bidir; - if (coord(line, start, &coord_end, &y_coord, &x_coord)) - return; + // net lines will be one of the following three types: + // in-port: net 1 in y68 x13 LOGIC 1 pin D3 + // out-port: net 1 out y72 x12 IOB 0 pin I + // switch: net 1 sw y72 x12 BIOB_IBUF0_PINW -> BIOB_IBUF0 - 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); + next_word(line, start, &net_idx_beg, &net_idx_end); + if (net_idx_end == net_idx_beg + || !all_digits(&line[net_idx_beg], net_idx_end-net_idx_beg)) + { HERE(); return; } + net_idx = to_i(&line[net_idx_beg], net_idx_end-net_idx_beg); + if (net_idx < 1) + { HERE(); return; } - 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(); + next_word(line, net_idx_end, &el_type_beg, &el_type_end); + if (!str_cmp(&line[el_type_beg], el_type_end-el_type_beg, "sw", 2)) { + struct sw_set sw; + + if (coord(line, el_type_end, &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); + + 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; + } + + sw.sw[0] = fpga_switch_lookup(model, y_coord, x_coord, from_str_i, to_str_i); + if (sw.sw[0] == NO_SWITCH) { + HERE(); + return; + } + sw_is_bidir = fpga_switch_is_bidir(model, y_coord, x_coord, sw.sw[0]); + if ((is_bidir && !sw_is_bidir) + || (!is_bidir && sw_is_bidir)) { + HERE(); + return; + } + if (fpga_switch_is_used(model, y_coord, x_coord, sw.sw[0])) + HERE(); + sw.len = 1; + if (fpga_net_add_switches(model, net_idx, y_coord, x_coord, &sw)) + HERE(); return; } - sw_idx = fpga_switch_lookup(model, y_coord, x_coord, from_str_i, to_str_i); - if (sw_idx == NO_SWITCH) { - HERE(); + if (str_cmp(&line[el_type_beg], el_type_end-el_type_beg, "in", 2) + && str_cmp(&line[el_type_beg], el_type_end-el_type_beg, "out", 3)) + { HERE(); return; } + + if (coord(line, el_type_end, &coord_end, &y_coord, &x_coord)) 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)) { + + next_word(line, coord_end, &dev_str_beg, &dev_str_end); + next_word(line, dev_str_end, &dev_type_idx_str_beg, &dev_type_idx_str_end); + next_word(line, dev_type_idx_str_end, &pin_str_beg, &pin_str_end); + next_word(line, pin_str_end, &pin_name_beg, &pin_name_end); + if (dev_str_end <= dev_str_beg + || dev_type_idx_str_end <= dev_type_idx_str_beg + || pin_str_end <= pin_str_beg + || pin_name_end <= pin_name_beg + || !all_digits(&line[dev_type_idx_str_beg], dev_type_idx_str_end-dev_type_idx_str_beg) + || str_cmp(&line[pin_str_beg], pin_str_end-pin_str_beg, "pin", 3)) + { HERE(); return; } + dev_type = fpgadev_str2type(&line[dev_str_beg], dev_str_end-dev_str_beg); + if (dev_type == DEV_NONE) { HERE(); return; } + dev_idx = fpga_dev_idx(model, y_coord, x_coord, dev_type, + to_i(&line[dev_type_idx_str_beg], + dev_type_idx_str_end-dev_type_idx_str_beg)); + if (dev_idx == NO_DEV) { HERE(); return; } + pinw_idx = fpgadev_pinw_str2idx(dev_type, &line[pin_name_beg], + pin_name_end-pin_name_beg); + if (pinw_idx == PINW_NO_IDX) { HERE(); return; } + if (fpga_net_add_port(model, net_idx, y_coord, x_coord, dev_idx, pinw_idx)) HERE(); - return; - } - if (fpga_switch_is_used(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) @@ -778,9 +824,9 @@ int read_floorplan(struct fpga_model* model, FILE* f) next_word(line, 0, &beg, &end); if (end == beg) continue; - 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, "net", 3)) { + read_net_line(model, line, end); } if (end-beg == 3 && !str_cmp(&line[beg], 3, "dev", 3)) { diff --git a/model.h b/model.h index 03192ae..cf07f18 100644 --- a/model.h +++ b/model.h @@ -509,11 +509,6 @@ int init_tiles(struct fpga_model* model); int init_devices(struct fpga_model* model); void free_devices(struct fpga_model* model); -const char* fpgadev_str(enum fpgadev_type type); -#define PINW_NO_IDX -1 -pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str); -// returns 0 when idx not found for the given devtype -const char* fpgadev_pinw_idx2str(int devtype, pinw_idx_t idx); int init_ports(struct fpga_model* model, int dup_warn); int init_conns(struct fpga_model* model); diff --git a/model_devices.c b/model_devices.c index fedd89d..67b1eae 100644 --- a/model_devices.c +++ b/model_devices.c @@ -333,62 +333,6 @@ void free_devices(struct fpga_model* model) } } -const char* fpgadev_str(enum fpgadev_type type) -{ - static const char* dev_str[] = FPGA_DEV_STR; - - if (type < 0 || type >= sizeof(dev_str)/sizeof(*dev_str)) - { HERE(); return 0; } - return dev_str[type]; -} - -static const char* iob_pinw_str[] = IOB_PINW_STR; -static const char* logic_pinw_str[] = LOGIC_PINW_STR; - -pinw_idx_t fpgadev_pinw_str2idx(int devtype, const char* str) -{ - int i; - - if (devtype == DEV_IOB) { - for (i = 0; i < sizeof(iob_pinw_str)/sizeof(*iob_pinw_str); i++) { - if (!strcmp(iob_pinw_str[i], str)) - return i; - } - HERE(); - return PINW_NO_IDX; - } - if (devtype == DEV_LOGIC) { - for (i = 0; i < sizeof(logic_pinw_str)/sizeof(*logic_pinw_str); i++) { - if (!strcmp(logic_pinw_str[i], str)) - return i; - } - HERE(); - return PINW_NO_IDX; - } - HERE(); - return PINW_NO_IDX; -} - -const char* fpgadev_pinw_idx2str(int devtype, pinw_idx_t idx) -{ - if (devtype == DEV_IOB) { - if (idx < 0 || idx >= sizeof(iob_pinw_str)/sizeof(*iob_pinw_str)) { - HERE(); - return 0; - } - return iob_pinw_str[idx]; - } - if (devtype == DEV_LOGIC) { - if (idx < 0 || idx >= sizeof(logic_pinw_str)/sizeof(*logic_pinw_str)) { - HERE(); - return 0; - } - return logic_pinw_str[idx]; - } - HERE(); - return 0; -} - #define DEV_INCREMENT 4 static int add_dev(struct fpga_model* model,