diff --git a/autotest.c b/autotest.c index d7e7e3b..d965039 100644 --- a/autotest.c +++ b/autotest.c @@ -107,9 +107,11 @@ int main(int argc, char** argv) { struct fpga_model model; struct fpga_device* P46_dev, *P48_dev, *logic_dev; - int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, dev_idx, rc; + int P46_y, P46_x, P46_dev_idx, P46_type_idx; + int P48_y, P48_x, P48_dev_idx, P48_type_idx, dev_idx, rc; struct test_state tstate; struct switch_to_yx switch_to; + net_idx_t P46_net; printf("\n"); printf("O fpgatools automatic test suite. Be welcome and be " @@ -135,22 +137,22 @@ int main(int argc, char** argv) if (rc) FAIL(rc); // configure P46 - rc = fpga_find_iob(&model, "P46", &P46_y, &P46_x, &P46_idx); + rc = fpga_find_iob(&model, "P46", &P46_y, &P46_x, &P46_type_idx); if (rc) FAIL(rc); - dev_idx = fpga_dev_idx(&model, P46_y, P46_x, DEV_IOB, P46_idx); - if (dev_idx == NO_DEV) FAIL(EINVAL); - P46_dev = FPGA_DEV(&model, P46_y, P46_x, dev_idx); + P46_dev_idx = fpga_dev_idx(&model, P46_y, P46_x, DEV_IOB, P46_type_idx); + if (P46_dev_idx == NO_DEV) FAIL(EINVAL); + P46_dev = FPGA_DEV(&model, P46_y, P46_x, P46_dev_idx); 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", &P48_y, &P48_x, &P48_idx); + rc = fpga_find_iob(&model, "P48", &P48_y, &P48_x, &P48_type_idx); if (rc) FAIL(rc); - dev_idx = fpga_dev_idx(&model, P48_y, P48_x, DEV_IOB, P48_idx); - if (dev_idx == NO_DEV) FAIL(EINVAL); - P48_dev = FPGA_DEV(&model, P48_y, P48_x, dev_idx); + P48_dev_idx = fpga_dev_idx(&model, P48_y, P48_x, DEV_IOB, P48_type_idx); + if (P48_dev_idx == NO_DEV) FAIL(EINVAL); + P48_dev = FPGA_DEV(&model, P48_y, P48_x, P48_dev_idx); P48_dev->instantiated = 1; strcpy(P48_dev->iob.ostandard, IO_LVCMOS33); P48_dev->iob.drive_strength = 12; @@ -170,6 +172,13 @@ int main(int argc, char** argv) rc = diff_printf(&tstate); if (rc) FAIL(rc); + // configure net from P46.I to logic.D3 + rc = fpga_net_new(&model, &P46_net); + if (rc) FAIL(rc); + rc = fpga_net_add_port(&model, P46_net, P46_y, P46_x, + P46_dev_idx, IOB_OUT_I); + if (rc) FAIL(rc); + printf("P46 I pinw %s\n", strarray_lookup(&model.str, P46_dev->pinw[IOB_OUT_I])); switch_to.yx_req = YX_DEV_ILOGIC; @@ -180,7 +189,8 @@ printf("P46 I pinw %s\n", strarray_lookup(&model.str, P46_dev->pinw[IOB_OUT_I])) switch_to.start_switch = P46_dev->pinw[IOB_OUT_I]; rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); - rc = fpga_switch_set_enable(&model, switch_to.y, switch_to.x, &switch_to.set); + rc = fpga_net_add_switches(&model, P46_net, switch_to.y, + switch_to.x, &switch_to.set); if (rc) FAIL(rc); printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_FROM)); @@ -192,7 +202,8 @@ printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_F switch_to.start_switch = switch_to.dest_connpt; rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); - rc = fpga_switch_set_enable(&model, switch_to.y, switch_to.x, &switch_to.set); + rc = fpga_net_add_switches(&model, P46_net, switch_to.y, + switch_to.x, &switch_to.set); if (rc) FAIL(rc); printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_FROM)); @@ -204,7 +215,8 @@ printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_F switch_to.start_switch = switch_to.dest_connpt; rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); - rc = fpga_switch_set_enable(&model, switch_to.y, switch_to.x, &switch_to.set); + rc = fpga_net_add_switches(&model, P46_net, switch_to.y, + switch_to.x, &switch_to.set); if (rc) FAIL(rc); printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_FROM)); @@ -229,7 +241,8 @@ printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_F } rc = fpga_switch_to_yx(&switch_to); if (rc) FAIL(rc); - rc = fpga_switch_set_enable(&model, switch_to.y, switch_to.x, &switch_to.set); + rc = fpga_net_add_switches(&model, P46_net, switch_to.y, + switch_to.x, &switch_to.set); if (rc) FAIL(rc); printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_FROM)); @@ -242,7 +255,7 @@ printf(" %s\n", fmt_swset(&model, switch_to.y, switch_to.x, &switch_to.set, SW_F .from_to = SW_FROM, .max_chain_size = MAX_SW_DEPTH }; if (fpga_switch_chain(&c) == NO_CONN) FAIL(EINVAL); if (c.set.len == 0) { HERE(); FAIL(EINVAL); } - rc = fpga_switch_set_enable(&model, c.y, c.x, &c.set); + rc = fpga_net_add_switches(&model, P46_net, c.y, c.x, &c.set); if (rc) FAIL(rc); printf(" %s\n", fmt_swset(&model, c.y, c.x, &c.set, SW_FROM)); } diff --git a/control.c b/control.c index 31b6133..92e0fb1 100644 --- a/control.c +++ b/control.c @@ -109,7 +109,7 @@ static const struct iob_site xc6slx9_iob_right[] = }; int fpga_find_iob(struct fpga_model* model, const char* sitename, - int* y, int* x, int* idx) + int* y, int* x, dev_type_idx_t* idx) { int i, j; @@ -157,7 +157,7 @@ int fpga_find_iob(struct fpga_model* model, const char* sitename, } const char* fpga_iob_sitename(struct fpga_model* model, int y, int x, - int idx) + dev_type_idx_t idx) { int i; @@ -751,36 +751,101 @@ int fpga_switch_to_yx(struct switch_to_yx* p) return 0; } +#define NET_ALLOC_INCREMENT 64 + int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx) { - return -1; + int rc; + + if (!(model->num_nets % NET_ALLOC_INCREMENT)) { + void* new_ptr; + int new_len; + + new_len = (model->num_nets+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->num_nets++; + *new_idx = model->num_nets; + return 0; +fail: + return rc; } int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next) { + int i; + + // last can be NO_NET which becomes 1 = the first net index + for (i = last+1; i <= model->num_nets; i++) { + if (model->nets[i-1].len) { + *next = i; + return 0; + } + } *next = NO_NET; return 0; } struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i) { - return 0; + if (net_i <= NO_NET + || net_i > model->num_nets) { + HERE(); + return 0; + } + return &model->nets[net_i-1]; } int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i, int y, int x, dev_idx_t dev_idx, pinw_idx_t pinw_idx) { - return -1; + struct fpga_net* net; + int rc; + + net = &model->nets[net_i-1]; + if (net->len >= MAX_NET_LEN) + FAIL(EINVAL); + net->el[net->len].y = y; + net->el[net->len].x = x; + net->el[net->len].idx = pinw_idx | NET_IDX_IS_PINW; + net->el[net->len].dev_idx = dev_idx; + net->len++; + return 0; +fail: + return rc; } int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, - const struct sw_set* set) + int y, int x, const struct sw_set* set) { - return -1; + struct fpga_net* net; + int i, rc; + + net = &model->nets[net_i-1]; + if (net->len+set->len > MAX_NET_LEN) + FAIL(EINVAL); + for (i = 0; i < set->len; i++) { + net->el[net->len].y = y; + net->el[net->len].x = x; + if (OUT_OF_U16(set->sw[i])) FAIL(EINVAL); + if (fpga_switch_is_used(model, y, x, set->sw[i])) + HERE(); + fpga_switch_enable(model, y, x, set->sw[i]); + net->el[net->len].idx = set->sw[i]; + net->len++; + } + return 0; +fail: + return rc; } void fpga_net_free_all(struct fpga_model* model) { free(model->nets); model->nets = 0; + model->num_nets = 0; } diff --git a/control.h b/control.h index 6ecb95b..9e8fdf8 100644 --- a/control.h +++ b/control.h @@ -6,10 +6,10 @@ // int fpga_find_iob(struct fpga_model* model, const char* sitename, - int* y, int* x, int* idx); + int* y, int* x, dev_type_idx_t* idx); const char* fpga_iob_sitename(struct fpga_model* model, int y, int x, - int idx); + dev_type_idx_t idx); // // When dealing with devices, there are two indices: @@ -175,7 +175,7 @@ int fpga_switch_to_yx(struct switch_to_yx* p); // connection points. For now we work with a simple // fixed-size array, we can later make this more dynamic // depending on which load on the memory manager is better. -#define MAX_NET_SIZE 128 +#define MAX_NET_LEN 128 #define NET_IDX_IS_PINW 0x8000 #define NET_IDX_MASK 0x7FFF @@ -193,11 +193,11 @@ struct net_el struct fpga_net { - int size; - struct net_el el[MAX_NET_SIZE]; + int len; + struct net_el el[MAX_NET_LEN]; }; -typedef int net_idx_t; +typedef int net_idx_t; // net indices are 1-based #define NO_NET 0 int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx); @@ -207,5 +207,5 @@ struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i); int fpga_net_add_port(struct fpga_model* model, net_idx_t net_i, int y, int x, dev_idx_t dev_idx, pinw_idx_t pinw_idx); int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, - const struct sw_set* set); + int y, int x, const struct sw_set* set); void fpga_net_free_all(struct fpga_model* model); diff --git a/helper.h b/helper.h index 10177b2..6b2e692 100644 --- a/helper.h +++ b/helper.h @@ -26,6 +26,8 @@ #define FAIL(code) do { HERE(); rc = (code); goto fail; } while (0) #define XOUT() do { HERE(); goto xout; } while (0) +#define OUT_OF_U16(val) ((val) < 0 || (val) > 0xFFFF) + const char* bitstr(uint32_t value, int digits); void hexdump(int indent, const uint8_t* data, int len); diff --git a/model.h b/model.h index afd1fb7..f8784ba 100644 --- a/model.h +++ b/model.h @@ -75,6 +75,7 @@ struct fpga_model struct fpga_tile* tiles; struct hashed_strarray str; + int num_nets; struct fpga_net* nets; // tmp_str will be allocated to hold max(x_width, y_height)