This commit is contained in:
Wolfgang Spraul 2012-08-04 03:35:54 +02:00
parent 5b9da5a1f1
commit ae2abbe06e
3 changed files with 157 additions and 13 deletions

View File

@ -16,6 +16,8 @@
#define PROGRAM_REVISION "2012-06-27" #define PROGRAM_REVISION "2012-06-27"
#define MACRO_STR(arg) #arg #define MACRO_STR(arg) #arg
#define ABORT(expr) if (expr) { fprintf(stderr, "Internal error in %s:%i\n", __FILE__, __LINE__); exit(1); }
void printf_help(); void printf_help();
const char* bitstr(uint32_t value, int digits); const char* bitstr(uint32_t value, int digits);

154
model.c
View File

@ -140,7 +140,7 @@ static int init_devices(struct fpga_model* model)
for (i = 0; i < model->cfg_rows; i++) { for (i = 0; i < model->cfg_rows; i++) {
y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE; y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs if (y > model->center_y) y++; // central regs
tile = YX_TILE(model, y-1, model->center_x-CMTPLL_FROM_CENTER_O); tile = YX_TILE(model, y-1, model->center_x-CENTER_CMTPLL_O);
if (i%2) { if (i%2) {
tile->devices[tile->num_devices++].type = DEV_DCM; tile->devices[tile->num_devices++].type = DEV_DCM;
tile->devices[tile->num_devices++].type = DEV_DCM; tile->devices[tile->num_devices++].type = DEV_DCM;
@ -180,7 +180,7 @@ static int init_devices(struct fpga_model* model)
tile->devices[tile->num_devices++].type = DEV_BUFGMUX; tile->devices[tile->num_devices++].type = DEV_BUFGMUX;
// BUFIO, BUFIO_FB, BUFPLL, BUFPLL_MCB // BUFIO, BUFIO_FB, BUFPLL, BUFPLL_MCB
tile = YX_TILE(model, TOP_OUTER_ROW, model->center_x-CMTPLL_FROM_CENTER_O); tile = YX_TILE(model, TOP_OUTER_ROW, model->center_x-CENTER_CMTPLL_O);
tile->devices[tile->num_devices++].type = DEV_BUFPLL; tile->devices[tile->num_devices++].type = DEV_BUFPLL;
tile->devices[tile->num_devices++].type = DEV_BUFPLL; tile->devices[tile->num_devices++].type = DEV_BUFPLL;
tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB; tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB;
@ -204,7 +204,7 @@ static int init_devices(struct fpga_model* model)
tile->devices[tile->num_devices++].type = DEV_BUFIO; tile->devices[tile->num_devices++].type = DEV_BUFIO;
tile->devices[tile->num_devices++].type = DEV_BUFIO_FB; tile->devices[tile->num_devices++].type = DEV_BUFIO_FB;
} }
tile = YX_TILE(model, model->y_height - BOT_OUTER_ROW, model->center_x-CMTPLL_FROM_CENTER_O); tile = YX_TILE(model, model->y_height - BOT_OUTER_ROW, model->center_x-CENTER_CMTPLL_O);
tile->devices[tile->num_devices++].type = DEV_BUFPLL; tile->devices[tile->num_devices++].type = DEV_BUFPLL;
tile->devices[tile->num_devices++].type = DEV_BUFPLL; tile->devices[tile->num_devices++].type = DEV_BUFPLL;
tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB; tile->devices[tile->num_devices++].type = DEV_BUFPLL_MCB;
@ -335,7 +335,7 @@ static int init_devices(struct fpga_model* model)
tile->devices[tile->num_devices++].type = DEV_TIEOFF; tile->devices[tile->num_devices++].type = DEV_TIEOFF;
tile = YX_TILE(model, TOP_OUTER_ROW, model->center_x-1); tile = YX_TILE(model, TOP_OUTER_ROW, model->center_x-1);
tile->devices[tile->num_devices++].type = DEV_TIEOFF; tile->devices[tile->num_devices++].type = DEV_TIEOFF;
tile = YX_TILE(model, model->y_height-BOT_OUTER_ROW, model->center_x-CMTPLL_FROM_CENTER_O); tile = YX_TILE(model, model->y_height-BOT_OUTER_ROW, model->center_x-CENTER_CMTPLL_O);
tile->devices[tile->num_devices++].type = DEV_TIEOFF; tile->devices[tile->num_devices++].type = DEV_TIEOFF;
for (x = 0; x < model->x_width; x++) { for (x = 0; x < model->x_width; x++) {
@ -599,15 +599,15 @@ static int init_wires(struct fpga_model* model)
{ {
int rc; int rc;
rc = run_direction_wires(model);
if (rc) goto xout;
rc = run_logic_inout(model); rc = run_logic_inout(model);
if (rc) goto xout; if (rc) goto xout;
rc = run_gclk(model); rc = run_gclk(model);
if (rc) goto xout; if (rc) goto xout;
rc = run_direction_wires(model);
if (rc) goto xout;
return 0; return 0;
xout: xout:
return rc; return rc;
@ -1309,11 +1309,70 @@ static int run_logic_inout(struct fpga_model* model)
} }
} }
} }
// LOGICIN
for (i = 0; i < model->cfg_rows; i++) {
y = TOP_IO_TILES + HALF_ROW + i*ROW_SIZE;
if (y > model->center_y) y++; // central regs
if (i%2) { // DCM
if ((rc = add_conn_range(model, NOPREF_BI_F,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 0, 3,
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB2_LOGICINB%i", 0))) goto xout;
if ((rc = add_conn_bi(model,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_IOI_LOGICBIN4",
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB2_LOGICINB4"))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 5, 9,
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB2_LOGICINB%i", 5))) goto xout;
if ((rc = add_conn_bi(model,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_IOI_LOGICBIN10",
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB2_LOGICINB10"))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 11, 62,
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB2_LOGICINB%i", 11))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y+1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 0, 3,
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB1_LOGICINB%i", 0))) goto xout;
if ((rc = add_conn_bi(model,
y+1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_IOI_LOGICBIN4",
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB1_LOGICINB4"))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y+1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 5, 9,
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB1_LOGICINB%i", 5))) goto xout;
if ((rc = add_conn_bi(model,
y+1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_IOI_LOGICBIN10",
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB1_LOGICINB10"))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y+1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 11, 62,
y-1, model->center_x-CENTER_CMTPLL_O, "DCM_CLB1_LOGICINB%i", 11))) goto xout;
} else { // PLL
if ((rc = add_conn_range(model, NOPREF_BI_F,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 0, 3,
y-1, model->center_x-CENTER_CMTPLL_O, "PLL_CLB2_LOGICINB%i", 0))) goto xout;
if ((rc = add_conn_bi(model,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_IOI_LOGICBIN4",
y-1, model->center_x-CENTER_CMTPLL_O, "PLL_CLB2_LOGICINB4"))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 5, 9,
y-1, model->center_x-CENTER_CMTPLL_O, "PLL_CLB2_LOGICINB%i", 5))) goto xout;
if ((rc = add_conn_bi(model,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_IOI_LOGICBIN10",
y-1, model->center_x-CENTER_CMTPLL_O, "PLL_CLB2_LOGICINB10"))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y-1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 11, 62,
y-1, model->center_x-CENTER_CMTPLL_O, "PLL_CLB2_LOGICINB%i", 11))) goto xout;
if ((rc = add_conn_range(model, NOPREF_BI_F,
y+1, model->center_x-CENTER_LOGIC_O, "INT_INTERFACE_LOGICBIN%i", 0, 62,
y-1, model->center_x-CENTER_CMTPLL_O, "PLL_CLB1_LOGICINB%i", 0))) goto xout;
}
}
for (y = 0; y < model->y_height; y++) { for (y = 0; y < model->y_height; y++) {
for (x = 0; x < model->x_width; x++) { for (x = 0; x < model->x_width; x++) {
tile = &model->tiles[y * model->x_width + x]; tile = &model->tiles[y * model->x_width + x];
// LOGICIN
if (is_atyx(YX_ROUTING_TILE, model, y, x)) { if (is_atyx(YX_ROUTING_TILE, model, y, x)) {
static const int north_p[4] = {21, 28, 52, 60}; static const int north_p[4] = {21, 28, 52, 60};
static const int south_p[4] = {20, 36, 44, 62}; static const int south_p[4] = {20, 36, 44, 62};
@ -1426,9 +1485,63 @@ xout:
return rc; return rc;
} }
static const char* s_4wire = "BAMCE";
static int run_direction_wires(struct fpga_model* model) static int run_direction_wires(struct fpga_model* model)
{ {
int x, y, rc; int x, y, i, j, _row_num, _row_pos, rc;
struct w_net net;
// NN4
for (x = 0; x < model->x_width; x++) {
if (!is_atx(X_ROUTING_COL, model, x))
continue;
for (y = 0; y < model->y_height; y++) {
is_in_row(model, y, &_row_num, &_row_pos);
if (_row_pos >= 0 && _row_pos != 8) {
net.last_inc = 3;
j = 0;
for (i = 0; i < 5; i++) { // go through "BAMCE"
net.pts[j].start_count = 0;
net.pts[j].y = y-j;
net.pts[j].x = x;
if (y-j == TOP_INNER_ROW) {
ABORT(!i);
net.pts[j].name = pf("NN4%c%%i", s_4wire[i-1]);
j++;
break;
}
net.pts[j].name = pf("NN4%c%%i", s_4wire[i]);
if (IS_CENTER_Y(y-j, model)
|| row_pos(y-j, model) == HCLK_POS) {
ABORT(!i);
i--;
}
j++;
}
net.pts[j].name = "";
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
}
}
if (!is_atx(X_FABRIC_BRAM_ROUTING_COL, model, x)) {
net.last_inc = 3;
for (i = 1; i < 5; i++) { // go through "BAMCE"
net.pts[0].start_count = 0;
net.pts[0].y = BOT_TERM(model);
net.pts[0].x = x;
net.pts[0].name = pf("NN4%c%%i", s_4wire[i]);
for (j = i; j < 5; j++) {
net.pts[j-i+1].start_count = 0;
net.pts[j-i+1].y = BOT_TERM(model)-(j-i+1);
net.pts[j-i+1].x = x;
net.pts[j-i+1].name = pf("NN4%c%%i", s_4wire[j]);
}
net.pts[j-i+1].name = "";
if ((rc = add_conn_net(model, PREF_BI_F, &net))) goto xout;
}
}
}
for (y = 0; y < model->y_height; y++) { for (y = 0; y < model->y_height; y++) {
for (x = 0; x < model->x_width; x++) { for (x = 0; x < model->x_width; x++) {
@ -2165,13 +2278,16 @@ static int init_tiles(struct fpga_model* model)
// helper funcs // helper funcs
// //
#define NUM_PF_BUFS 16
static const char* pf(const char* fmt, ...) static const char* pf(const char* fmt, ...)
{ {
// safe to call it 8 times in 1 expression (such as function params) // safe to call it NUM_PF_BUFStimes in 1 expression,
static char pf_buf[8][128]; // such as function params or a net structure
static char pf_buf[NUM_PF_BUFS][128];
static int last_buf = 0; static int last_buf = 0;
va_list list; va_list list;
last_buf = (last_buf+1)%8; last_buf = (last_buf+1)%NUM_PF_BUFS;
pf_buf[last_buf][0] = 0; pf_buf[last_buf][0] = 0;
va_start(list, fmt); va_start(list, fmt);
vsnprintf(pf_buf[last_buf], sizeof(pf_buf[0]), fmt, list); vsnprintf(pf_buf[last_buf], sizeof(pf_buf[0]), fmt, list);
@ -2607,6 +2723,20 @@ void is_in_row(const struct fpga_model* model, int y,
if (row_pos) *row_pos = y%(8+1+8); if (row_pos) *row_pos = y%(8+1+8);
} }
int row_num(int y, struct fpga_model* model)
{
int result;
is_in_row(model, y, &result, 0 /* row_pos */);
return result;
}
int row_pos(int y, struct fpga_model* model)
{
int result;
is_in_row(model, y, 0 /* row_num */, &result);
return result;
}
static const char* fpga_ttstr[] = // tile type strings static const char* fpga_ttstr[] = // tile type strings
{ {
[NA] = "NA", [NA] = "NA",

14
model.h
View File

@ -139,6 +139,7 @@ enum fpga_tile_type
#define TOP_OUTER_ROW 0 #define TOP_OUTER_ROW 0
#define TOP_INNER_ROW 1 #define TOP_INNER_ROW 1
#define HALF_ROW 8 #define HALF_ROW 8
#define HCLK_POS 8 // hclk pos in row
#define LAST_POS_IN_ROW 16 // including hclk at 8 #define LAST_POS_IN_ROW 16 // including hclk at 8
#define ROW_SIZE (HALF_ROW+1+HALF_ROW) #define ROW_SIZE (HALF_ROW+1+HALF_ROW)
@ -151,7 +152,9 @@ enum fpga_tile_type
#define RIGHT_MCB_O 3 #define RIGHT_MCB_O 3
#define RIGHT_IO_DEVS_O 4 #define RIGHT_IO_DEVS_O 4
#define RIGHT_IO_ROUTING_O 5 #define RIGHT_IO_ROUTING_O 5
#define CMTPLL_FROM_CENTER_O 1 #define CENTER_CMTPLL_O 1
#define CENTER_LOGIC_O 2
#define CENTER_ROUTING_O 3
#define YX_TILE(model, y, x) (&(model)->tiles[(y)*model->x_width+(x)]) #define YX_TILE(model, y, x) (&(model)->tiles[(y)*model->x_width+(x)])
@ -218,6 +221,11 @@ int is_aty(int check, struct fpga_model* model, int y);
#define X_LEFT_MCB 0x04000000 #define X_LEFT_MCB 0x04000000
#define X_RIGHT_MCB 0x08000000 #define X_RIGHT_MCB 0x08000000
#define IS_TOP_ROW(row, model) ((row) == (model)->cfg_rows-1)
#define IS_BOTTOM_ROW(row, model) ((row) == 0)
#define IS_CENTER_Y(row, model) ((row) == (model)->center_y)
#define BOT_TERM(model) ((model)->y_height-BOT_INNER_ROW)
// multiple checks are combined with OR logic // multiple checks are combined with OR logic
int is_atx(int check, struct fpga_model* model, int x); int is_atx(int check, struct fpga_model* model, int x);
@ -232,6 +240,10 @@ int is_atyx(int check, struct fpga_model* model, int y, int x);
void is_in_row(const struct fpga_model* model, int y, void is_in_row(const struct fpga_model* model, int y,
int* row_num, int* row_pos); int* row_num, int* row_pos);
// row_num() and row_pos() return -1 if y is outside of a row
int row_num(int y, struct fpga_model* model);
int row_pos(int y, struct fpga_model* model);
enum fpgadev_type enum fpgadev_type
{ {
DEV_LOGIC_M, DEV_LOGIC_M,