232 lines
7.3 KiB
C
232 lines
7.3 KiB
C
//
|
|
// 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 <stdarg.h>
|
|
#include "model.h"
|
|
#include "parts.h"
|
|
|
|
static int s_high_speed_replicate = 1;
|
|
|
|
int fpga_build_model(struct fpga_model* model, int fpga_rows,
|
|
const char* columns, const char* left_wiring, const char* right_wiring)
|
|
{
|
|
int rc;
|
|
|
|
memset(model, 0, sizeof(*model));
|
|
model->cfg_rows = fpga_rows;
|
|
strncpy(model->cfg_columns, columns, sizeof(model->cfg_columns)-1);
|
|
strncpy(model->cfg_left_wiring, left_wiring,
|
|
sizeof(model->cfg_left_wiring)-1);
|
|
strncpy(model->cfg_right_wiring, right_wiring,
|
|
sizeof(model->cfg_right_wiring)-1);
|
|
strarray_init(&model->str, STRIDX_64K);
|
|
rc = get_xc6_routing_bitpos(&model->sw_bitpos, &model->num_bitpos);
|
|
if (rc) FAIL(rc);
|
|
|
|
// The order of tiles, then devices, then ports, then
|
|
// connections and finally switches is important so
|
|
// that the codes can build upon each other.
|
|
|
|
rc = init_tiles(model);
|
|
if (rc) FAIL(rc);
|
|
|
|
rc = init_devices(model);
|
|
if (rc) FAIL(rc);
|
|
|
|
if (s_high_speed_replicate) {
|
|
rc = replicate_routing_switches(model);
|
|
if (rc) FAIL(rc);
|
|
}
|
|
|
|
// todo: compare.ports only works if other switches and conns
|
|
// are disabled, as long as not all connections are supported
|
|
rc = init_ports(model, /*dup_warn*/ !s_high_speed_replicate);
|
|
if (rc) FAIL(rc);
|
|
|
|
rc = init_conns(model);
|
|
if (rc) FAIL(rc);
|
|
|
|
rc = init_switches(model, /*routing_sw*/ !s_high_speed_replicate);
|
|
if (rc) FAIL(rc);
|
|
return 0;
|
|
fail:
|
|
return rc;
|
|
}
|
|
|
|
void fpga_free_model(struct fpga_model* model)
|
|
{
|
|
if (!model) return;
|
|
free_devices(model);
|
|
free(model->tmp_str);
|
|
strarray_free(&model->str);
|
|
free(model->tiles);
|
|
free_xc6_routing_bitpos(model->sw_bitpos);
|
|
memset(model, 0, sizeof(*model));
|
|
}
|
|
|
|
static const char* fpga_ttstr[] = // tile type strings
|
|
{
|
|
[NA] = "NA",
|
|
[ROUTING] = "ROUTING",
|
|
[ROUTING_BRK] = "ROUTING_BRK",
|
|
[ROUTING_VIA] = "ROUTING_VIA",
|
|
[HCLK_ROUTING_XM] = "HCLK_ROUTING_XM",
|
|
[HCLK_ROUTING_XL] = "HCLK_ROUTING_XL",
|
|
[HCLK_LOGIC_XM] = "HCLK_LOGIC_XM",
|
|
[HCLK_LOGIC_XL] = "HCLK_LOGIC_XL",
|
|
[LOGIC_XM] = "LOGIC_XM",
|
|
[LOGIC_XL] = "LOGIC_XL",
|
|
[REGH_ROUTING_XM] = "REGH_ROUTING_XM",
|
|
[REGH_ROUTING_XL] = "REGH_ROUTING_XL",
|
|
[REGH_LOGIC_XM] = "REGH_LOGIC_XM",
|
|
[REGH_LOGIC_XL] = "REGH_LOGIC_XL",
|
|
[BRAM_ROUTING] = "BRAM_ROUTING",
|
|
[BRAM_ROUTING_BRK] = "BRAM_ROUTING_BRK",
|
|
[BRAM] = "BRAM",
|
|
[BRAM_ROUTING_TERM_T] = "BRAM_ROUTING_TERM_T",
|
|
[BRAM_ROUTING_TERM_B] = "BRAM_ROUTING_TERM_B",
|
|
[BRAM_ROUTING_VIA_TERM_T] = "BRAM_ROUTING_VIA_TERM_T",
|
|
[BRAM_ROUTING_VIA_TERM_B] = "BRAM_ROUTING_VIA_TERM_B",
|
|
[BRAM_TERM_LT] = "BRAM_TERM_LT",
|
|
[BRAM_TERM_RT] = "BRAM_TERM_RT",
|
|
[BRAM_TERM_LB] = "BRAM_TERM_LB",
|
|
[BRAM_TERM_RB] = "BRAM_TERM_RB",
|
|
[HCLK_BRAM_ROUTING] = "HCLK_BRAM_ROUTING",
|
|
[HCLK_BRAM_ROUTING_VIA] = "HCLK_BRAM_ROUTING_VIA",
|
|
[HCLK_BRAM] = "HCLK_BRAM",
|
|
[REGH_BRAM_ROUTING] = "REGH_BRAM_ROUTING",
|
|
[REGH_BRAM_ROUTING_VIA] = "REGH_BRAM_ROUTING_VIA",
|
|
[REGH_BRAM_L] = "REGH_BRAM_L",
|
|
[REGH_BRAM_R] = "REGH_BRAM_R",
|
|
[MACC] = "MACC",
|
|
[HCLK_MACC_ROUTING] = "HCLK_MACC_ROUTING",
|
|
[HCLK_MACC_ROUTING_VIA] = "HCLK_MACC_ROUTING_VIA",
|
|
[HCLK_MACC] = "HCLK_MACC",
|
|
[REGH_MACC_ROUTING] = "REGH_MACC_ROUTING",
|
|
[REGH_MACC_ROUTING_VIA] = "REGH_MACC_ROUTING_VIA",
|
|
[REGH_MACC_L] = "REGH_MACC_L",
|
|
[PLL_T] = "PLL_T",
|
|
[DCM_T] = "DCM_T",
|
|
[PLL_B] = "PLL_B",
|
|
[DCM_B] = "DCM_B",
|
|
[REG_T] = "REG_T",
|
|
[REG_TERM_T] = "REG_TERM_T",
|
|
[REG_TERM_B] = "REG_TERM_B",
|
|
[REG_B] = "REG_B",
|
|
[REGV_TERM_T] = "REGV_TERM_T",
|
|
[REGV_TERM_B] = "REGV_TERM_B",
|
|
[HCLK_REGV] = "HCLK_REGV",
|
|
[REGV] = "REGV",
|
|
[REGV_BRK] = "REGV_BRK",
|
|
[REGV_T] = "REGV_T",
|
|
[REGV_B] = "REGV_B",
|
|
[REGV_MIDBUF_T] = "REGV_MIDBUF_T",
|
|
[REGV_HCLKBUF_T] = "REGV_HCLKBUF_T",
|
|
[REGV_HCLKBUF_B] = "REGV_HCLKBUF_B",
|
|
[REGV_MIDBUF_B] = "REGV_MIDBUF_B",
|
|
[REGC_ROUTING] = "REGC_ROUTING",
|
|
[REGC_LOGIC] = "REGC_LOGIC",
|
|
[REGC_CMT] = "REGC_CMT",
|
|
[CENTER] = "CENTER",
|
|
[IO_T] = "IO_T",
|
|
[IO_B] = "IO_B",
|
|
[IO_TERM_T] = "IO_TERM_T",
|
|
[IO_TERM_B] = "IO_TERM_B",
|
|
[IO_ROUTING] = "IO_ROUTING",
|
|
[IO_LOGIC_TERM_T] = "IO_LOGIC_TERM_T",
|
|
[IO_LOGIC_TERM_B] = "IO_LOGIC_TERM_B",
|
|
[IO_OUTER_T] = "IO_OUTER_T",
|
|
[IO_INNER_T] = "IO_INNER_T",
|
|
[IO_OUTER_B] = "IO_OUTER_B",
|
|
[IO_INNER_B] = "IO_INNER_B",
|
|
[IO_BUFPLL_TERM_T] = "IO_BUFPLL_TERM_T",
|
|
[IO_LOGIC_REG_TERM_T] = "IO_LOGIC_REG_TERM_T",
|
|
[IO_BUFPLL_TERM_B] = "IO_BUFPLL_TERM_B",
|
|
[IO_LOGIC_REG_TERM_B] = "IO_LOGIC_REG_TERM_B",
|
|
[LOGIC_ROUTING_TERM_B] = "LOGIC_ROUTING_TERM_B",
|
|
[LOGIC_NOIO_TERM_B] = "LOGIC_NOIO_TERM_B",
|
|
[MACC_ROUTING_TERM_T] = "MACC_ROUTING_TERM_T",
|
|
[MACC_ROUTING_TERM_B] = "MACC_ROUTING_TERM_B",
|
|
[MACC_VIA_TERM_T] = "MACC_VIA_TERM_T",
|
|
[MACC_TERM_TL] = "MACC_TERM_TL",
|
|
[MACC_TERM_TR] = "MACC_TERM_TR",
|
|
[MACC_TERM_BL] = "MACC_TERM_BL",
|
|
[MACC_TERM_BR] = "MACC_TERM_BR",
|
|
[ROUTING_VIA_REGC] = "ROUTING_VIA_REGC",
|
|
[ROUTING_VIA_IO] = "ROUTING_VIA_IO",
|
|
[ROUTING_VIA_IO_DCM] = "ROUTING_VIA_IO_DCM",
|
|
[ROUTING_VIA_CARRY] = "ROUTING_VIA_CARRY",
|
|
[CORNER_TERM_L] = "CORNER_TERM_L",
|
|
[CORNER_TERM_R] = "CORNER_TERM_R",
|
|
[IO_TERM_L_UPPER_TOP] = "IO_TERM_L_UPPER_TOP",
|
|
[IO_TERM_L_UPPER_BOT] = "IO_TERM_L_UPPER_BOT",
|
|
[IO_TERM_L_LOWER_TOP] = "IO_TERM_L_LOWER_TOP",
|
|
[IO_TERM_L_LOWER_BOT] = "IO_TERM_L_LOWER_BOT",
|
|
[IO_TERM_R_UPPER_TOP] = "IO_TERM_R_UPPER_TOP",
|
|
[IO_TERM_R_UPPER_BOT] = "IO_TERM_R_UPPER_BOT",
|
|
[IO_TERM_R_LOWER_TOP] = "IO_TERM_R_LOWER_TOP",
|
|
[IO_TERM_R_LOWER_BOT] = "IO_TERM_R_LOWER_BOT",
|
|
[IO_TERM_L] = "IO_TERM_L",
|
|
[IO_TERM_R] = "IO_TERM_R",
|
|
[HCLK_TERM_L] = "HCLK_TERM_L",
|
|
[HCLK_TERM_R] = "HCLK_TERM_R",
|
|
[REGH_IO_TERM_L] = "REGH_IO_TERM_L",
|
|
[REGH_IO_TERM_R] = "REGH_IO_TERM_R",
|
|
[REG_L] = "REG_L",
|
|
[REG_R] = "REG_R",
|
|
[IO_PCI_L] = "IO_PCI_L",
|
|
[IO_PCI_R] = "IO_PCI_R",
|
|
[IO_RDY_L] = "IO_RDY_L",
|
|
[IO_RDY_R] = "IO_RDY_R",
|
|
[IO_L] = "IO_L",
|
|
[IO_R] = "IO_R",
|
|
[IO_PCI_CONN_L] = "IO_PCI_CONN_L",
|
|
[IO_PCI_CONN_R] = "IO_PCI_CONN_R",
|
|
[CORNER_TERM_T] = "CORNER_TERM_T",
|
|
[CORNER_TERM_B] = "CORNER_TERM_B",
|
|
[ROUTING_IO_L] = "ROUTING_IO_L",
|
|
[HCLK_ROUTING_IO_L] = "HCLK_ROUTING_IO_L",
|
|
[HCLK_ROUTING_IO_R] = "HCLK_ROUTING_IO_R",
|
|
[REGH_ROUTING_IO_L] = "REGH_ROUTING_IO_L",
|
|
[REGH_ROUTING_IO_R] = "REGH_ROUTING_IO_R",
|
|
[ROUTING_IO_L_BRK] = "ROUTING_IO_L_BRK",
|
|
[ROUTING_GCLK] = "ROUTING_GCLK",
|
|
[REGH_IO_L] = "REGH_IO_L",
|
|
[REGH_IO_R] = "REGH_IO_R",
|
|
[REGH_MCB] = "REGH_MCB",
|
|
[HCLK_MCB] = "HCLK_MCB",
|
|
[ROUTING_IO_VIA_L] = "ROUTING_IO_VIA_L",
|
|
[ROUTING_IO_VIA_R] = "ROUTING_IO_VIA_R",
|
|
[ROUTING_IO_PCI_CE_L] = "ROUTING_IO_PCI_CE_L",
|
|
[ROUTING_IO_PCI_CE_R] = "ROUTING_IO_PCI_CE_R",
|
|
[CORNER_TL] = "CORNER_TL",
|
|
[CORNER_BL] = "CORNER_BL",
|
|
[CORNER_TR_UPPER] = "CORNER_TR_UPPER",
|
|
[CORNER_TR_LOWER] = "CORNER_TR_LOWER",
|
|
[CORNER_BR_UPPER] = "CORNER_BR_UPPER",
|
|
[CORNER_BR_LOWER] = "CORNER_BR_LOWER",
|
|
[HCLK_IO_TOP_UP_L] = "HCLK_IO_TOP_UP_L",
|
|
[HCLK_IO_TOP_UP_R] = "HCLK_IO_TOP_UP_R",
|
|
[HCLK_IO_TOP_SPLIT_L] = "HCLK_IO_TOP_SPLIT_L",
|
|
[HCLK_IO_TOP_SPLIT_R] = "HCLK_IO_TOP_SPLIT_R",
|
|
[HCLK_IO_TOP_DN_L] = "HCLK_IO_TOP_DN_L",
|
|
[HCLK_IO_TOP_DN_R] = "HCLK_IO_TOP_DN_R",
|
|
[HCLK_IO_BOT_UP_L] = "HCLK_IO_BOT_UP_L",
|
|
[HCLK_IO_BOT_UP_R] = "HCLK_IO_BOT_UP_R",
|
|
[HCLK_IO_BOT_SPLIT_L] = "HCLK_IO_BOT_SPLIT_L",
|
|
[HCLK_IO_BOT_SPLIT_R] = "HCLK_IO_BOT_SPLIT_R",
|
|
[HCLK_IO_BOT_DN_L] = "HCLK_IO_BOT_DN_L",
|
|
[HCLK_IO_BOT_DN_R] = "HCLK_IO_BOT_DN_R",
|
|
};
|
|
|
|
const char* fpga_tiletype_str(enum fpga_tile_type type)
|
|
{
|
|
if (type >= sizeof(fpga_ttstr)/sizeof(fpga_ttstr[0])
|
|
|| !fpga_ttstr[type]) return "UNK";
|
|
return fpga_ttstr[type];
|
|
}
|