diff --git a/autotest.c b/autotest.c index 8f34602..d7e7e3b 100644 --- a/autotest.c +++ b/autotest.c @@ -107,7 +107,7 @@ 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, rc; + int P46_y, P46_x, P46_idx, P48_y, P48_x, P48_idx, dev_idx, rc; struct test_state tstate; struct switch_to_yx switch_to; @@ -137,8 +137,9 @@ int main(int argc, char** argv) // configure P46 rc = fpga_find_iob(&model, "P46", &P46_y, &P46_x, &P46_idx); if (rc) FAIL(rc); - P46_dev = fpga_dev(&model, P46_y, P46_x, DEV_IOB, P46_idx); - if (!P46_dev) FAIL(EINVAL); + 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->instantiated = 1; strcpy(P46_dev->iob.istandard, IO_LVCMOS33); P46_dev->iob.bypass_mux = BYPASS_MUX_I; @@ -147,8 +148,9 @@ int main(int argc, char** argv) // configure P48 rc = fpga_find_iob(&model, "P48", &P48_y, &P48_x, &P48_idx); if (rc) FAIL(rc); - P48_dev = fpga_dev(&model, P48_y, P48_x, DEV_IOB, P48_idx); - if (!P48_dev) FAIL(EINVAL); + 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->instantiated = 1; strcpy(P48_dev->iob.ostandard, IO_LVCMOS33); P48_dev->iob.drive_strength = 12; @@ -157,8 +159,9 @@ int main(int argc, char** argv) P48_dev->iob.suspend = SUSP_3STATE; // configure logic - logic_dev = fpga_dev(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX); - if (!logic_dev) FAIL(EINVAL); + dev_idx = fpga_dev_idx(&model, /*y*/ 68, /*x*/ 13, DEV_LOGIC, DEV_LOGX); + if (dev_idx == NO_DEV) FAIL(EINVAL); + logic_dev = FPGA_DEV(&model, /*y*/ 68, /*x*/ 13, dev_idx); logic_dev->instantiated = 1; logic_dev->logic.D_used = 1; rc = fpga_set_lut(&model, logic_dev, D6_LUT, "A3", ZTERM); diff --git a/bit_frames.c b/bit_frames.c index 279b38d..706a0d5 100644 --- a/bit_frames.c +++ b/bit_frames.c @@ -75,7 +75,7 @@ static struct bit_pos s_default_bits[] = { int extract_model(struct fpga_model* model, struct fpga_bits* bits) { - int i, num_iobs, iob_y, iob_x, iob_idx, row, row_pos, rc; + int i, num_iobs, iob_y, iob_x, iob_idx, dev_idx, row, row_pos, rc; int x, y, byte_off; uint32_t* u32_p; uint8_t* u8_p; @@ -102,8 +102,9 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) } rc = fpga_find_iob(model, iob_sitename, &iob_y, &iob_x, &iob_idx); if (rc) FAIL(rc); - dev = fpga_dev(model, iob_y, iob_x, DEV_IOB, iob_idx); - if (!dev) FAIL(rc); + dev_idx = fpga_dev_idx(model, iob_y, iob_x, DEV_IOB, iob_idx); + if (dev_idx == NO_DEV) FAIL(EINVAL); + dev = FPGA_DEV(model, iob_y, iob_x, dev_idx); // we only support 2 hardcoded types of IOB right now // todo: bit 7 goes on when out-net connected? @@ -173,8 +174,9 @@ int extract_model(struct fpga_model* model, struct fpga_bits* bits) clear_bit(bits, /*row*/ 0, /*major*/ 17, /*minor*/ 22, /*bit_i*/ 980); - dev = fpga_dev(model, y, x, DEV_LOGIC, DEV_LOGX); - if (!dev) FAIL(EINVAL); + dev_idx = fpga_dev_idx(model, y, x, DEV_LOGIC, DEV_LOGX); + if (dev_idx == NO_DEV) FAIL(EINVAL); + dev = FPGA_DEV(model, y, x, dev_idx); dev->instantiated = 1; *(uint64_t*)(u8_p+26*FRAME_SIZE+byte_off) = 0; diff --git a/control.c b/control.c index 5c330df..31b6133 100644 --- a/control.c +++ b/control.c @@ -200,34 +200,35 @@ const char* fpga_iob_sitename(struct fpga_model* model, int y, int x, return 0; } -struct fpga_device* fpga_dev(struct fpga_model* model, - int y, int x, enum fpgadev_type type, int type_idx) +dev_idx_t fpga_dev_idx(struct fpga_model* model, + int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx) { struct fpga_tile* tile; - int type_count, i; + dev_type_idx_t type_count; + dev_idx_t i; tile = YX_TILE(model, y, x); type_count = 0; for (i = 0; i < tile->num_devs; i++) { if (tile->devs[i].type == type) { if (type_count == type_idx) - return &tile->devs[i]; + return i; type_count++; } } - return 0; + return NO_DEV; } -int fpga_dev_typecount(struct fpga_model* model, int y, int x, - enum fpgadev_type type, int dev_idx) +dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x, + dev_idx_t dev_idx) { struct fpga_tile* tile; - int type_count, i; + dev_type_idx_t type_count, i; tile = YX_TILE(model, y, x); type_count = 0; for (i = 0; i < dev_idx; i++) { - if (tile->devs[i].type == type) + if (tile->devs[i].type == tile->devs[dev_idx].type) type_count++; } return type_count; @@ -749,3 +750,37 @@ int fpga_switch_to_yx(struct switch_to_yx* p) } return 0; } + +int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx) +{ + return -1; +} + +int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next) +{ + *next = NO_NET; + return 0; +} + +struct fpga_net* fpga_net_get(struct fpga_model* model, net_idx_t net_i) +{ + return 0; +} + +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; +} + +int fpga_net_add_switches(struct fpga_model* model, net_idx_t net_i, + const struct sw_set* set) +{ + return -1; +} + +void fpga_net_free_all(struct fpga_model* model) +{ + free(model->nets); + model->nets = 0; +} diff --git a/control.h b/control.h index 7776464..6ecb95b 100644 --- a/control.h +++ b/control.h @@ -17,14 +17,14 @@ 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. // -// Looks up a device pointer based on the type index. -struct fpga_device* fpga_dev(struct fpga_model* model, - int y, int x, enum fpgadev_type type, int type_idx); +// Looks up a device index based on the type index. +dev_idx_t fpga_dev_idx(struct fpga_model* model, + int y, int x, enum fpgadev_type type, dev_type_idx_t type_idx); -// Counts how many devices of type 'type' are in the device -// array up to devidx. -int fpga_dev_typecount(struct fpga_model* model, int y, int x, - enum fpgadev_type type, int dev_idx); +// Counts how many devices of the same type as dev_idx are in +// the array up to dev_idx. +dev_type_idx_t fpga_dev_typeidx(struct fpga_model* model, int y, int x, + dev_idx_t dev_idx); enum { A6_LUT, B6_LUT, C6_LUT, D6_LUT }; // lut_len can be -1 (ZTERM) @@ -41,6 +41,10 @@ int fpga_connpt_find(struct fpga_model* model, int y, int x, 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); +// +// switches +// + typedef int swidx_t; // swidx_t is an index into the uint32_t switches array #define MAX_SW_DEPTH 64 // largest seen so far was 20 @@ -161,3 +165,47 @@ struct switch_to_yx }; int fpga_switch_to_yx(struct switch_to_yx* p); + +// +// nets +// + +// The last m1 soc has about 20k nets with about 470k +// connection points. The largest net has about 110 +// 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 NET_IDX_IS_PINW 0x8000 +#define NET_IDX_MASK 0x7FFF + +struct net_el +{ + uint16_t y; + uint16_t x; + // idx is either an index into tile->switches[] + // if bit15 (NET_IDX_IS_PINW) is off, or an index + // into dev->pinw[] if bit15 is on. + uint16_t idx; + uint16_t dev_idx; // only used if idx&NET_IDX_IS_PINW +}; + +struct fpga_net +{ + int size; + struct net_el el[MAX_NET_SIZE]; +}; + +typedef int net_idx_t; +#define NO_NET 0 + +int fpga_net_new(struct fpga_model* model, net_idx_t* new_idx); +// start a new enumeration by calling with last==NO_NET +int fpga_net_enum(struct fpga_model* model, net_idx_t last, net_idx_t* next); +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); +void fpga_net_free_all(struct fpga_model* model); diff --git a/floorplan.c b/floorplan.c index 714a373..b8df162 100644 --- a/floorplan.c +++ b/floorplan.c @@ -772,7 +772,7 @@ 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; + int dev_type_idx, dev_idx, words_consumed; struct fpga_device* dev_ptr; int next_beg, next_end, second_beg, second_end; @@ -788,12 +788,13 @@ static void read_dev_line(struct fpga_model* model, const char* line, int start) 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) { + dev_type_idx = to_i(&line[idx_beg], idx_end-idx_beg); + dev_idx = fpga_dev_idx(model, y_coord, x_coord, dev_type, dev_type_idx); + if (dev_idx == NO_DEV) { fprintf(stderr, "error %i: %s", __LINE__, line); return; } + dev_ptr = FPGA_DEV(model, y_coord, x_coord, dev_idx); next_end = idx_end; while (next_word(line, next_end, &next_beg, &next_end), diff --git a/model.h b/model.h index 9e4c85b..afd1fb7 100644 --- a/model.h +++ b/model.h @@ -75,6 +75,8 @@ struct fpga_model struct fpga_tile* tiles; struct hashed_strarray str; + struct fpga_net* nets; + // tmp_str will be allocated to hold max(x_width, y_height) // pointers, useful for string seeding when running wires. const char** tmp_str; @@ -331,6 +333,21 @@ enum fpgadev_type DEV_SPI_ACCESS }; +// We use two types of device indices, one is a flat index +// into the tile->devs array (dev_idx_t), the other +// one counts up from 0 through devices of one particular +// type in the tile. The first logic device has type_idx == 0, +// the second logic device has type_idx == 1, etc, no matter +// at which index they are in the device array. The type indices +// are used in the floorplan, the flat array indices internally +// in memory. + +typedef int dev_idx_t; +typedef int dev_type_idx_t; + +#define NO_DEV -1 +#define FPGA_DEV(model, y, x, dev_idx) (&YX_TILE(model, y, x)->devs[dev_idx]) + // M and L device is always at type index 0, X device // is always at type index 1. #define DEV_LOGM 0 diff --git a/model_devices.c b/model_devices.c index 00f9930..a202fe1 100644 --- a/model_devices.c +++ b/model_devices.c @@ -424,7 +424,7 @@ static int init_iob(struct fpga_model* model, int y, int x, tile = YX_TILE(model, y, x); tile->devs[idx].iob.subtype = subtype; - type_idx = fpga_dev_typecount(model, y, x, DEV_IOB, idx); + type_idx = fpga_dev_typeidx(model, y, x, idx); if (!y) prefix = "TIOB"; else if (y == model->y_height - BOT_OUTER_ROW)