fpgatools/libs/model_main.c
2012-09-19 21:49:30 +08:00

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];
}