From d1e8d5f557cae96630c4903ca4f18cd1567f23b3 Mon Sep 17 00:00:00 2001 From: Wolfgang Spraul Date: Tue, 17 Jul 2012 10:58:07 +0200 Subject: [PATCH] moved model into separate file so multiple utils can use it --- .gitignore | 5 +- Makefile | 22 +-- draw_svg_tiles.c | 103 ++++++++++++ draw_fpga.c => model.c | 363 +---------------------------------------- model.h | 141 ++++++++++++++++ 5 files changed, 266 insertions(+), 368 deletions(-) create mode 100644 draw_svg_tiles.c rename draw_fpga.c => model.c (75%) create mode 100644 model.h diff --git a/.gitignore b/.gitignore index dbc6a38..df2433f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ bit2txt bit2txt.o -draw_fpga -draw_fpga.o +draw_svg_tiles +draw_svg_tiles.o helper.o +model.o diff --git a/Makefile b/Makefile index a9e02d9..d78dc15 100644 --- a/Makefile +++ b/Makefile @@ -6,24 +6,26 @@ # For details see the UNLICENSE file at the root of the source tree. # +.PHONY: all clean CFLAGS = -Wall -g -#TARGETS = bit2txt draw_fpga -#OBJS = $(TARGETS:=.o) LDLIBS = -lxml2 -all: bit2txt draw_fpga xc6slx9.svg +all: bit2txt draw_svg_tiles xc6slx9.svg -xc6slx9.svg: draw_fpga - ./draw_fpga --svg | xmllint --pretty 1 - > $@ +xc6slx9.svg: draw_svg_tiles + ./draw_svg_tiles | xmllint --pretty 1 - > $@ bit2txt: bit2txt.o helper.o -bit2txt.o:bit2txt.c helper.h +bit2txt.o: bit2txt.c helper.h -helper.o:helper.c helper.h +helper.o: helper.c helper.h -draw_fpga: draw_fpga.o +model.o: model.c model.h + +draw_svg_tiles: draw_svg_tiles.o model.o clean: - rm -f bit2txt bit2txt.o helper.o draw_fpga -.PHONY: all clean + rm -f bit2txt bit2txt.o \ + draw_svg_tiles draw_svg_tiles.o \ + helper.o model.o diff --git a/draw_svg_tiles.c b/draw_svg_tiles.c new file mode 100644 index 0000000..61fd723 --- /dev/null +++ b/draw_svg_tiles.c @@ -0,0 +1,103 @@ +// +// Author: Wolfgang Spraul +// +// This is free and unencumbered software released into the public domain. +// For details see the UNLICENSE file at the root of the source tree. +// + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "model.h" + +void print_svg_tiles(struct fpga_model* model); + +int main(int argc, char** argv) +{ + static const xmlChar* empty_svg = (const xmlChar*) + "\n" + "\n" + "\n" + "\n"; + + xmlDocPtr doc = 0; + xmlXPathContextPtr xpathCtx = 0; + xmlXPathObjectPtr xpathObj = 0; + xmlNodePtr new_node; + struct fpga_model* model = 0; + char str[128]; + int i, j; + +// can't get indent formatting to work - use 'xmllint --pretty 1 -' +// on the output for now + + xmlInitParser(); + model = fpga_build_model(XC6SLX9_ROWS, XC6SLX9_COLUMNS, + XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING); + if (!model) goto fail; + + doc = xmlParseDoc(empty_svg); + if (!doc) { + fprintf(stderr, "Internal error %i.\n", __LINE__); + goto fail; + } + xpathCtx = xmlXPathNewContext(doc); + if (!xpathCtx) { + fprintf(stderr, "Cannot create XPath context.\n"); + goto fail; + } + xmlXPathRegisterNs(xpathCtx, BAD_CAST "svg", BAD_CAST "http://www.w3.org/2000/svg"); + xpathObj = xmlXPathEvalExpression(BAD_CAST "//svg:*[@id='root']", xpathCtx); + if (!xpathObj) { + fprintf(stderr, "Cannot evaluate root expression.\n"); + goto fail; + } + if (!xpathObj->nodesetval) { + fprintf(stderr, "Cannot find root node.\n"); + goto fail; + } + if (xpathObj->nodesetval->nodeNr != 1) { + fprintf(stderr, "Found %i root nodes.\n", xpathObj->nodesetval->nodeNr); + goto fail; + } + + for (i = 0; i < model->tile_y_range; i++) { + for (j = 0; j < model->tile_x_range; j++) { + strcpy(str, fpga_tiletype_str(model->tiles[i*model->tile_x_range+j].type)); + new_node = xmlNewChild(xpathObj->nodesetval->nodeTab[0], 0 /* xmlNsPtr */, BAD_CAST "text", BAD_CAST str); + xmlSetProp(new_node, BAD_CAST "x", xmlXPathCastNumberToString(130 + j*130)); + xmlSetProp(new_node, BAD_CAST "y", xmlXPathCastNumberToString(40 + i*14)); + xmlSetProp(new_node, BAD_CAST "fpga:tile_y", BAD_CAST xmlXPathCastNumberToString(i)); + xmlSetProp(new_node, BAD_CAST "fpga:tile_x", BAD_CAST xmlXPathCastNumberToString(j)); + } + } + xmlSetProp(xpathObj->nodesetval->nodeTab[0], BAD_CAST "width", BAD_CAST xmlXPathCastNumberToString(model->tile_x_range * 130 + 65)); + xmlSetProp(xpathObj->nodesetval->nodeTab[0], BAD_CAST "height", BAD_CAST xmlXPathCastNumberToString(model->tile_y_range * 14 + 60)); + + xmlDocFormatDump(stdout, doc, 1 /* format */); + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + xmlCleanupParser(); + return EXIT_SUCCESS; + +fail: + if (xpathObj) xmlXPathFreeObject(xpathObj); + if (xpathCtx) xmlXPathFreeContext(xpathCtx); + if (doc) xmlFreeDoc(doc); + xmlCleanupParser(); + return EXIT_FAILURE; +} diff --git a/draw_fpga.c b/model.c similarity index 75% rename from draw_fpga.c rename to model.c index 179d3e4..6c30d2a 100644 --- a/draw_fpga.c +++ b/model.c @@ -5,180 +5,9 @@ // For details see the UNLICENSE file at the root of the source tree. // -#include -#include -#include -#include -#include -#include +#include "model.h" -#include -#include -#include -#include - -struct fpga_model -{ - int tile_x_range, tile_y_range; - struct fpga_tile* tiles; -}; - -enum fpga_tile_type -{ - NA, - ROUTING, - ROUTING_BRK, - ROUTING_VIA, - HCLK_ROUTING_XM, - HCLK_ROUTING_XL, - HCLK_LOGIC_XM, - HCLK_LOGIC_XL, - LOGIC_XM, - LOGIC_XL, - REGH_ROUTING_XM, - REGH_ROUTING_XL, - REGH_LOGIC_XM, - REGH_LOGIC_XL, - BRAM_ROUTING, - BRAM_ROUTING_BRK, - BRAM, - BRAM_ROUTING_TERM_T, - BRAM_ROUTING_TERM_B, - BRAM_ROUTING_VIA_TERM_T, - BRAM_ROUTING_VIA_TERM_B, - BRAM_TERM_LT, - BRAM_TERM_RT, - BRAM_TERM_LB, - BRAM_TERM_RB, - HCLK_BRAM_ROUTING, - HCLK_BRAM_ROUTING_VIA, - HCLK_BRAM, - REGH_BRAM_ROUTING, - REGH_BRAM_ROUTING_VIA, - REGH_BRAM_L, - REGH_BRAM_R, - MACC, - HCLK_MACC_ROUTING, - HCLK_MACC_ROUTING_VIA, - HCLK_MACC, - REGH_MACC_ROUTING, - REGH_MACC_ROUTING_VIA, - REGH_MACC_L, - PLL_T, - DCM_T, - PLL_B, - DCM_B, - REG_T, - REG_TERM_T, - REG_TERM_B, - REG_B, - REGV_TERM_T, - REGV_TERM_B, - HCLK_REGV, - REGV, - REGV_BRK, - REGV_T, - REGV_B, - REGV_MIDBUF_T, - REGV_HCLKBUF_T, - REGV_HCLKBUF_B, - REGV_MIDBUF_B, - REGC_ROUTING, - REGC_LOGIC, - REGC_CMT, - CENTER, // unique center tile in the middle of the chip - IO_T, - IO_B, - IO_TERM_T, - IO_TERM_B, - IO_ROUTING, - IO_LOGIC_TERM_T, - IO_LOGIC_TERM_B, - IO_OUTER_T, - IO_INNER_T, - IO_OUTER_B, - IO_INNER_B, - IO_BUFPLL_TERM_T, - IO_LOGIC_REG_TERM_T, - IO_BUFPLL_TERM_B, - IO_LOGIC_REG_TERM_B, - LOGIC_ROUTING_TERM_B, - LOGIC_NOIO_TERM_B, - MACC_ROUTING_TERM_T, - MACC_ROUTING_TERM_B, - MACC_VIA_TERM_T, - MACC_TERM_TL, - MACC_TERM_TR, - MACC_TERM_BL, - MACC_TERM_BR, - ROUTING_VIA_REGC, - ROUTING_VIA_IO, - ROUTING_VIA_IO_DCM, - ROUTING_VIA_CARRY, - CORNER_TERM_L, - CORNER_TERM_R, - IO_TERM_L_UPPER_TOP, - IO_TERM_L_UPPER_BOT, - IO_TERM_L_LOWER_TOP, - IO_TERM_L_LOWER_BOT, - IO_TERM_R_UPPER_TOP, - IO_TERM_R_UPPER_BOT, - IO_TERM_R_LOWER_TOP, - IO_TERM_R_LOWER_BOT, - IO_TERM_L, - IO_TERM_R, - HCLK_TERM_L, - HCLK_TERM_R, - REGH_IO_TERM_L, - REGH_IO_TERM_R, - REG_L, - REG_R, - IO_PCI_L, - IO_PCI_R, - IO_RDY_L, - IO_RDY_R, - IO_L, - IO_R, - IO_PCI_CONN_L, - IO_PCI_CONN_R, - CORNER_TERM_T, - CORNER_TERM_B, - ROUTING_IO_L, - HCLK_ROUTING_IO_L, - HCLK_ROUTING_IO_R, - REGH_ROUTING_IO_L, - REGH_ROUTING_IO_R, - ROUTING_IO_L_BRK, - ROUTING_GCLK, - REGH_IO_L, - REGH_IO_R, - REGH_MCB, - HCLK_MCB, - ROUTING_IO_VIA_L, - ROUTING_IO_VIA_R, - ROUTING_IO_PCI_CE_L, - ROUTING_IO_PCI_CE_R, - CORNER_TL, - CORNER_BL, - CORNER_TR_UPPER, - CORNER_TR_LOWER, - CORNER_BR_UPPER, - CORNER_BR_LOWER, - HCLK_IO_TOP_UP_L, - HCLK_IO_TOP_UP_R, - HCLK_IO_TOP_SPLIT_L, - HCLK_IO_TOP_SPLIT_R, - HCLK_IO_TOP_DN_L, - HCLK_IO_TOP_DN_R, - HCLK_IO_BOT_UP_L, - HCLK_IO_BOT_UP_R, - HCLK_IO_BOT_SPLIT_L, - HCLK_IO_BOT_SPLIT_R, - HCLK_IO_BOT_DN_L, - HCLK_IO_BOT_DN_R, -}; - -const char* fpga_ttstr[] = // tile type strings +static const char* fpga_ttstr[] = // tile type strings { [NA] = "NA", [ROUTING] = "ROUTING", @@ -333,103 +162,7 @@ const char* fpga_ttstr[] = // tile type strings [HCLK_IO_BOT_DN_R] = "HCLK_IO_BOT_DN_R", }; -struct fpga_tile -{ - enum fpga_tile_type type; - - // expect up to 64 devices per tile - int num_devices; - struct fpga_device* devices; - - // expect up to 28k connections to other tiles per tile - // 3*16 bit per connection: - // - x coordinate of other tile (16bit) - // - y coordinate of other tile (16bit) - // - endpoint index in other tile (16bit) - int num_conns; // conns array is 3*num_conns 16-bit words - uint16_t* conns; // num_conns*3 16-bit words: 16(x)-16(y)-16(endpoint) - - // expect up to 5k endpoints per tile - // 16-bit index into conns (not yet multiplied by 3) - int num_endpoints; - uint16_t* endpoints; - // endpoints0 are conceptual endpoints without outgoing wires. - // Imagine their indices added to the end of num_endpoints, so - // the first endpoint0 is at index num_endpoints, the second one - // at num_endpoints+1, and so on. - int num_endpoints0; - - // expect up to 4k connection pairs per tile - // 32bit: 31 off: not in use on: used - // 30 off: unidirectional on: bidirectional - // 29:15 from, index into endpoints - // 14:0 to, index into endpoints - int num_connect_pairs; - uint32_t* connect_pairs; -}; - -// columns -// 'L' = X+L logic block -// 'l' = X+L logic block without IO at top and bottom -// 'M' = X+M logic block -// 'm' = X+M logic block without IO at top and bottom -// 'B' = block ram -// 'D' = dsp (macc) -// 'R' = registers and center IO/logic column -// -// wiring on the left and right side is described with 16 -// characters for each row - 'W' = wired, 'U' = unwired -// order is top-down - -#define XC6SLX9_ROWS 4 -#define XC6SLX9_COLUMNS "MLBMLDMRMlMLBML" -#define XC6SLX9_LEFT_WIRING \ - /* row 3 */ "UWUWUWUW" "WWWWUUUU" \ - /* row 2 */ "UUUUUUUU" "WWWWWWUU" \ - /* row 1 */ "WWWUUWUU" "WUUWUUWU" \ - /* row 0 */ "UWUUWUUW" "UUWWWWUU" -#define XC6SLX9_RIGHT_WIRING \ - /* row 3 */ "UUWWUWUW" "WWWWUUUU" \ - /* row 2 */ "UUUUUUUU" "WWWWWWUU" \ - /* row 1 */ "WWWUUWUU" "WUUWUUWU" \ - /* row 0 */ "UWUUWUUW" "UUWWWWUU" - -struct fpga_model* build_model(int fpga_rows, const char* columns, - const char* left_wiring, const char* right_wiring); -void print_svg_tiles(struct fpga_model* model); -void write_folders(struct fpga_model* model, const char* root_folder); - -int main(int argc, char** argv) -{ - struct fpga_model* model = 0; - - if (argc < 2) { - printf("\n" - "draw_fpga - model and view of an FPGA\n" - "Public domain work by Wolfgang Spraul\n" - "\n" - "draw_fpga [options]\n" - " --svg writes a simple svg tile grid to stdout\n" - " --folder writes a folder structure of tiles and devices\n" - "\n"); - return EXIT_SUCCESS; - } - - model = build_model(XC6SLX9_ROWS, XC6SLX9_COLUMNS, - XC6SLX9_LEFT_WIRING, XC6SLX9_RIGHT_WIRING); - if (!model) goto fail; - - if (!strcmp(argv[1], "--svg")) - print_svg_tiles(model); - if (!strcmp(argv[1], "--folder")) - write_folders(model, argv[2]); - - return EXIT_SUCCESS; -fail: - return EXIT_FAILURE; -} - -struct fpga_model* build_model(int fpga_rows, const char* columns, +struct fpga_model* fpga_build_model(int fpga_rows, const char* columns, const char* left_wiring, const char* right_wiring) { int tile_rows, tile_columns, i, j, k, l, row_top_y, center_row, left_side; @@ -897,91 +630,9 @@ struct fpga_model* build_model(int fpga_rows, const char* columns, return model; } -void print_svg_tiles(struct fpga_model* model) +const char* fpga_tiletype_str(enum fpga_tile_type type) { - static const xmlChar* empty_svg = (const xmlChar*) - "\n" - "\n" - "\n" - "\n"; - - xmlDocPtr doc = 0; - xmlXPathContextPtr xpathCtx = 0; - xmlXPathObjectPtr xpathObj = 0; - xmlNodePtr new_node; - char str[128]; - int i, j; - -// can't get indent formatting to work - use 'xmllint --pretty 1 -' -// on the output for now - - xmlInitParser(); - doc = xmlParseDoc(empty_svg); - if (!doc) { - fprintf(stderr, "Internal error %i.\n", __LINE__); - goto fail; - } - xpathCtx = xmlXPathNewContext(doc); - if (!xpathCtx) { - fprintf(stderr, "Cannot create XPath context.\n"); - goto fail; - } - xmlXPathRegisterNs(xpathCtx, BAD_CAST "svg", BAD_CAST "http://www.w3.org/2000/svg"); - xpathObj = xmlXPathEvalExpression(BAD_CAST "//svg:*[@id='root']", xpathCtx); - if (!xpathObj) { - fprintf(stderr, "Cannot evaluate root expression.\n"); - goto fail; - } - if (!xpathObj->nodesetval) { - fprintf(stderr, "Cannot find root node.\n"); - goto fail; - } - if (xpathObj->nodesetval->nodeNr != 1) { - fprintf(stderr, "Found %i root nodes.\n", xpathObj->nodesetval->nodeNr); - goto fail; - } - - for (i = 0; i < model->tile_y_range; i++) { - for (j = 0; j < model->tile_x_range; j++) { - strcpy(str, fpga_ttstr[model->tiles[i*model->tile_x_range+j].type]); - new_node = xmlNewChild(xpathObj->nodesetval->nodeTab[0], 0 /* xmlNsPtr */, BAD_CAST "text", BAD_CAST str); - xmlSetProp(new_node, BAD_CAST "x", xmlXPathCastNumberToString(130 + j*130)); - xmlSetProp(new_node, BAD_CAST "y", xmlXPathCastNumberToString(40 + i*14)); - xmlSetProp(new_node, BAD_CAST "fpga:tile_y", BAD_CAST xmlXPathCastNumberToString(i)); - xmlSetProp(new_node, BAD_CAST "fpga:tile_x", BAD_CAST xmlXPathCastNumberToString(j)); - } - } - xmlSetProp(xpathObj->nodesetval->nodeTab[0], BAD_CAST "width", BAD_CAST xmlXPathCastNumberToString(model->tile_x_range * 130 + 65)); - xmlSetProp(xpathObj->nodesetval->nodeTab[0], BAD_CAST "height", BAD_CAST xmlXPathCastNumberToString(model->tile_y_range * 14 + 60)); - - xmlDocFormatDump(stdout, doc, 1 /* format */); - xmlXPathFreeObject(xpathObj); - xmlXPathFreeContext(xpathCtx); - xmlFreeDoc(doc); - xmlCleanupParser(); - return; - -fail: - if (xpathObj) xmlXPathFreeObject(xpathObj); - if (xpathCtx) xmlXPathFreeContext(xpathCtx); - if (doc) xmlFreeDoc(doc); - xmlCleanupParser(); -} - -void write_folders(struct fpga_model* model, const char* root_folder) -{ - char path[1024]; - - sprintf(path, "%s/devices", root_folder); - if (mkdir(path, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH)) { - fprintf(stderr, "Cannot create folder %s\n", path); - return; - } - - // root/devices/IOB - // root/tile_type/1file_per_tile + if (type >= sizeof(fpga_ttstr)/sizeof(fpga_ttstr[0]) + || !fpga_ttstr[type]) return "UNK"; + return fpga_ttstr[type]; } diff --git a/model.h b/model.h new file mode 100644 index 0000000..27cb1d4 --- /dev/null +++ b/model.h @@ -0,0 +1,141 @@ +// +// Author: Wolfgang Spraul +// +// This is free and unencumbered software released into the public domain. +// For details see the UNLICENSE file at the root of the source tree. +// + +#include +#include +#include +#include +#include +#include + +// columns +// 'L' = X+L logic block +// 'l' = X+L logic block without IO at top and bottom +// 'M' = X+M logic block +// 'm' = X+M logic block without IO at top and bottom +// 'B' = block ram +// 'D' = dsp (macc) +// 'R' = registers and center IO/logic column +// +// wiring on the left and right side is described with 16 +// characters for each row - 'W' = wired, 'U' = unwired +// order is top-down + +#define XC6SLX9_ROWS 4 +#define XC6SLX9_COLUMNS "MLBMLDMRMlMLBML" +#define XC6SLX9_LEFT_WIRING \ + /* row 3 */ "UWUWUWUW" "WWWWUUUU" \ + /* row 2 */ "UUUUUUUU" "WWWWWWUU" \ + /* row 1 */ "WWWUUWUU" "WUUWUUWU" \ + /* row 0 */ "UWUUWUUW" "UUWWWWUU" +#define XC6SLX9_RIGHT_WIRING \ + /* row 3 */ "UUWWUWUW" "WWWWUUUU" \ + /* row 2 */ "UUUUUUUU" "WWWWWWUU" \ + /* row 1 */ "WWWUUWUU" "WUUWUUWU" \ + /* row 0 */ "UWUUWUUW" "UUWWWWUU" + +struct fpga_model +{ + int tile_x_range, tile_y_range; + struct fpga_tile* tiles; +}; + +enum fpga_tile_type +{ + NA, + ROUTING, ROUTING_BRK, ROUTING_VIA, + HCLK_ROUTING_XM, HCLK_ROUTING_XL, HCLK_LOGIC_XM, HCLK_LOGIC_XL, + LOGIC_XM, LOGIC_XL, + REGH_ROUTING_XM, REGH_ROUTING_XL, REGH_LOGIC_XM, REGH_LOGIC_XL, + BRAM_ROUTING, BRAM_ROUTING_BRK, + BRAM, + BRAM_ROUTING_TERM_T, BRAM_ROUTING_TERM_B, BRAM_ROUTING_VIA_TERM_T, BRAM_ROUTING_VIA_TERM_B, + BRAM_TERM_LT, BRAM_TERM_RT, BRAM_TERM_LB, BRAM_TERM_RB, + HCLK_BRAM_ROUTING, HCLK_BRAM_ROUTING_VIA, HCLK_BRAM, + REGH_BRAM_ROUTING, REGH_BRAM_ROUTING_VIA, REGH_BRAM_L, REGH_BRAM_R, + MACC, + HCLK_MACC_ROUTING, HCLK_MACC_ROUTING_VIA, HCLK_MACC, + REGH_MACC_ROUTING, REGH_MACC_ROUTING_VIA, REGH_MACC_L, + PLL_T, DCM_T, PLL_B, DCM_B, REG_T, + REG_TERM_T, REG_TERM_B, REG_B, + REGV_TERM_T, REGV_TERM_B, + HCLK_REGV, + REGV, REGV_BRK, REGV_T, REGV_B, REGV_MIDBUF_T, REGV_HCLKBUF_T, REGV_HCLKBUF_B, REGV_MIDBUF_B, + REGC_ROUTING, REGC_LOGIC, REGC_CMT, + CENTER, // unique center tile in the middle of the chip + IO_T, IO_B, IO_TERM_T, IO_TERM_B, IO_ROUTING, IO_LOGIC_TERM_T, IO_LOGIC_TERM_B, + IO_OUTER_T, IO_INNER_T, IO_OUTER_B, IO_INNER_B, + IO_BUFPLL_TERM_T, IO_LOGIC_REG_TERM_T, IO_BUFPLL_TERM_B, IO_LOGIC_REG_TERM_B, + LOGIC_ROUTING_TERM_B, LOGIC_NOIO_TERM_B, + MACC_ROUTING_TERM_T, MACC_ROUTING_TERM_B, MACC_VIA_TERM_T, + MACC_TERM_TL, MACC_TERM_TR, MACC_TERM_BL, MACC_TERM_BR, + ROUTING_VIA_REGC, ROUTING_VIA_IO, ROUTING_VIA_IO_DCM, ROUTING_VIA_CARRY, + CORNER_TERM_L, CORNER_TERM_R, + IO_TERM_L_UPPER_TOP, IO_TERM_L_UPPER_BOT, IO_TERM_L_LOWER_TOP, IO_TERM_L_LOWER_BOT, + IO_TERM_R_UPPER_TOP, IO_TERM_R_UPPER_BOT, IO_TERM_R_LOWER_TOP, IO_TERM_R_LOWER_BOT, + IO_TERM_L, IO_TERM_R, + HCLK_TERM_L, HCLK_TERM_R, + REGH_IO_TERM_L, REGH_IO_TERM_R, + REG_L, REG_R, + IO_PCI_L, IO_PCI_R, IO_RDY_L, IO_RDY_R, + IO_L, IO_R, + IO_PCI_CONN_L, IO_PCI_CONN_R, + CORNER_TERM_T, CORNER_TERM_B, + ROUTING_IO_L, + HCLK_ROUTING_IO_L, HCLK_ROUTING_IO_R, REGH_ROUTING_IO_L, REGH_ROUTING_IO_R, + ROUTING_IO_L_BRK, ROUTING_GCLK, + REGH_IO_L, REGH_IO_R, REGH_MCB, HCLK_MCB, + ROUTING_IO_VIA_L, ROUTING_IO_VIA_R, ROUTING_IO_PCI_CE_L, ROUTING_IO_PCI_CE_R, + CORNER_TL, CORNER_BL, + CORNER_TR_UPPER, CORNER_TR_LOWER, CORNER_BR_UPPER, CORNER_BR_LOWER, + HCLK_IO_TOP_UP_L, HCLK_IO_TOP_UP_R, + HCLK_IO_TOP_SPLIT_L, HCLK_IO_TOP_SPLIT_R, + HCLK_IO_TOP_DN_L, HCLK_IO_TOP_DN_R, + HCLK_IO_BOT_UP_L, HCLK_IO_BOT_UP_R, + HCLK_IO_BOT_SPLIT_L, HCLK_IO_BOT_SPLIT_R, + HCLK_IO_BOT_DN_L, HCLK_IO_BOT_DN_R, +}; + +struct fpga_tile +{ + enum fpga_tile_type type; + + // expect up to 64 devices per tile + int num_devices; + struct fpga_device* devices; + + // expect up to 28k connections to other tiles per tile + // 3*16 bit per connection: + // - x coordinate of other tile (16bit) + // - y coordinate of other tile (16bit) + // - endpoint index in other tile (16bit) + int num_conns; // conns array is 3*num_conns 16-bit words + uint16_t* conns; // num_conns*3 16-bit words: 16(x)-16(y)-16(endpoint) + + // expect up to 5k endpoints per tile + // 16-bit index into conns (not yet multiplied by 3) + int num_endpoints; + uint16_t* endpoints; + // endpoints0 are conceptual endpoints without outgoing wires. + // Imagine their indices added to the end of num_endpoints, so + // the first endpoint0 is at index num_endpoints, the second one + // at num_endpoints+1, and so on. + int num_endpoints0; + + // expect up to 4k connection pairs per tile + // 32bit: 31 off: not in use on: used + // 30 off: unidirectional on: bidirectional + // 29:15 from, index into endpoints + // 14:0 to, index into endpoints + int num_connect_pairs; + uint32_t* connect_pairs; +}; + +struct fpga_model* fpga_build_model(int fpga_rows, const char* columns, + const char* left_wiring, const char* right_wiring); + +const char* fpga_tiletype_str(enum fpga_tile_type type);