This commit is contained in:
Wolfgang Spraul 2012-07-24 15:38:01 +02:00
parent 7f74817e78
commit 44cd3b0b7f
3 changed files with 183 additions and 45 deletions

155
model.c
View File

@ -190,6 +190,8 @@ int fpga_build_model(struct fpga_model* model, int fpga_rows, const char* column
#define CONN_NAMES_INCREMENT 128
#define CONNS_INCREMENT 128
#undef DBG_ADD_CONN_UNI
int add_conn_uni(struct fpga_model* model, int y1, int x1, const char* name1, int y2, int x2, const char* name2)
{
struct fpga_tile* tile1;
@ -233,7 +235,14 @@ int add_conn_uni(struct fpga_model* model, int y1, int x1, const char* name1, in
if (tile1->conns[j*3] == x2
&& tile1->conns[j*3+1] == y2
&& tile1->conns[j*3+2] == name2_i) {
fprintf(stderr, "Internal error, connection made twice.\n");
fprintf(stderr, "Duplicate conn (num_conns %i): y%02i x%02i %s - y%02i x%02i %s.\n",
num_conns_for_this_wire, y1, x1, name1, y2, x2, name2);
for (j = conn_start; j < conn_start + num_conns_for_this_wire; j++) {
fprintf(stderr, "c%i: y%02i x%02i %s -> y%02i x%02i %s\n", j,
y1, x1, name1,
tile1->conns[j*3+1], tile1->conns[j*3],
strarray_lookup(&model->str, tile1->conns[j*3+2]));
}
return 0;
}
}
@ -252,6 +261,18 @@ int add_conn_uni(struct fpga_model* model, int y1, int x1, const char* name1, in
tile1->conns[j*3+1] = y2;
tile1->conns[j*3+2] = name2_i;
tile1->num_conns++;
while (i+1 < tile1->num_conn_names) {
tile1->conn_names[(i+1)*2]++;
i++;
}
#if DBG_ADD_CONN_UNI
printf("conns for y%02i x%02i %s now:\n", y1, x1, name1);
for (j = conn_start; j < conn_start + num_conns_for_this_wire+1; j++) {
fprintf(stderr, "c%i: y%02i x%02i %s -> y%02i x%02i %s\n", j, y1, x1, name1,
tile1->conns[j*3+1], tile1->conns[j*3],
strarray_lookup(&model->str, tile1->conns[j*3+2]));
}
#endif
return 0;
}
@ -278,7 +299,7 @@ const char* pf(const char* fmt, ...)
int run_wires(struct fpga_model* model)
{
struct fpga_tile* tile, *tile_up1, *tile_up2;
struct fpga_tile* tile, *tile_up1, *tile_up2, *tile_dn1, *tile_dn2;
char b_wire[16], m_wire[16], e_wire[16], r1b_wire[16], r1e_wire[16];
char* wire_fmt;
int x, y, i, rc;
@ -290,33 +311,85 @@ int run_wires(struct fpga_model* model)
tile = &model->tiles[y * model->tile_x_range + x];
tile_up1 = &model->tiles[(y-1) * model->tile_x_range + x];
tile_up2 = &model->tiles[(y-2) * model->tile_x_range + x];
tile_dn1 = &model->tiles[(y+1) * model->tile_x_range + x];
tile_dn2 = &model->tiles[(y+2) * model->tile_x_range + x];
if (!(tile->flags & TF_DIRWIRE_START)) {
if (tile->flags & TF_VERT_ROUTING) {
if (tile_up1->flags & (TF_ROW_HORIZ_AXSYMM | TF_CHIP_HORIZ_AXSYMM)) {
if (tile->flags & TF_VERT_ROUTING) {
// NR1B-NR1E
if (tile_up1->flags & TF_UNDER_TOPMOST_TILE) {
for (i = 0; i <= 3; i++) {
if ((rc = add_conn_bi(model, y, x, pf("NR1B%i", i), y-1, x, pf("IOI_TTERM_NR1B%i", i)))) goto xout;
}
} else if (tile_up1->flags & (TF_ROW_HORIZ_AXSYMM | TF_CHIP_HORIZ_AXSYMM)) {
if (tile_up1->flags & TF_ROW_HORIZ_AXSYMM)
wire_fmt = "HCLK_%s";
else if (tile[3].flags & TF_CHIP_VERT_AXSYMM)
wire_fmt = "REGC_INT_%s";
else
wire_fmt = "REGH_%s";
for (i = 0; i <= 3; i++) {
sprintf(r1b_wire, "NR1B%i", i);
sprintf(r1e_wire, "NR1E%i", i);
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-1, x, pf(wire_fmt, r1e_wire)))) goto xout;
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-2, x, r1e_wire))) goto xout;
}
} else {
for (i = 0; i <= 3; i++) {
if ((rc = add_conn_bi(model, y, x, pf("NR1B%i", i), y-1, x, pf("NR1E%i", i)))) goto xout;
if (tile_up1->flags & TF_ROW_HORIZ_AXSYMM)
wire_fmt = "HCLK_%s";
else if (tile[3].flags & TF_CHIP_VERT_AXSYMM)
wire_fmt = "REGC_INT_%s";
else
wire_fmt = "REGH_%s";
for (i = 0; i <= 3; i++) {
sprintf(r1b_wire, "NR1B%i", i);
sprintf(r1e_wire, "NR1E%i", i);
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-1, x, pf(wire_fmt, r1e_wire)))) goto xout;
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-2, x, r1e_wire))) goto xout;
if ((rc = add_conn_bi(model, y-1, x, pf(wire_fmt, r1e_wire), y-2, x, r1e_wire))) goto xout;
}
} else {
for (i = 0; i <= 3; i++) {
if ((rc = add_conn_bi(model, y, x, pf("NR1B%i", i), y-1, x, pf("NR1E%i", i)))) goto xout;
if (tile->flags & TF_MACC_COL && tile_dn1->flags & TF_ABOVE_BOTTOMMOST_TILE) {
if ((rc = add_conn_bi(model, y, x, pf("NR1E%i", i), y+1, x, pf("IOI_BTERM_NR1E%i", i)))) goto xout;
}
}
}
// NN2E_S0
if (tile_up1->flags & TF_UNDER_TOPMOST_TILE) {
if ((rc = add_conn_bi(model, y, x, "NN2E_S0", y-1, x, "IOI_TTERM_NN2E_S0"))) goto xout;
} else if (tile_up2->flags & TF_UNDER_TOPMOST_TILE) {
} else if (tile_up1->flags & (TF_ROW_HORIZ_AXSYMM | TF_CHIP_HORIZ_AXSYMM)) {
if (tile_up1->flags & TF_ROW_HORIZ_AXSYMM)
wire_fmt = "HCLK_%s";
else if (tile[3].flags & TF_CHIP_VERT_AXSYMM)
wire_fmt = "REGC_INT_%s";
else
wire_fmt = "REGH_%s";
if ((rc = add_conn_bi(model, y-1, x, pf(wire_fmt, "NN2M0"), y-2, x, "NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y-3, x, "NN2E0", y-2, x, "NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y, x, "NN2B0", y-2, x, "NN2E_S0"))) goto xout;
} else if (tile_up2->flags & (TF_ROW_HORIZ_AXSYMM | TF_CHIP_HORIZ_AXSYMM)) {
if (tile_up2->flags & TF_ROW_HORIZ_AXSYMM)
wire_fmt = "HCLK_%s";
else if (tile[3].flags & TF_CHIP_VERT_AXSYMM)
wire_fmt = "REGC_INT_%s";
else
wire_fmt = "REGH_%s";
if ((rc = add_conn_bi(model, y-2, x, pf(wire_fmt, "NN2E0"), y-1, x, "NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y, x, "NN2B0", y-2, x, pf(wire_fmt, "NN2E_S0")))) goto xout;
if ((rc = add_conn_bi(model, y-2, x, pf(wire_fmt, "NN2E_S0"), y-1, x, "NN2M0"))) goto xout;
if ((rc = add_conn_bi(model, y-2, x, pf(wire_fmt, "NN2E_S0"), y-1, x, "NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y-2, x, pf(wire_fmt, "NN2E_S0"), y-3, x, "NN2E0"))) goto xout;
if ((rc = add_conn_bi(model, y-3, x, "NN2E0", y-1, x, "NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y, x, "NN2B0", y-1, x, "NN2E_S0"))) goto xout;
} else {
if ((rc = add_conn_bi(model, y, x, "NN2B0", y-1, x, "NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y-2, x, "NN2E0", y-1, x, "NN2E_S0"))) goto xout;
if (tile_dn1->flags & TF_ABOVE_BOTTOMMOST_TILE) {
if ((rc = add_conn_bi(model, y, x, "NN2E_S0", y-1, x, "NN2E0"))) goto xout;
if (!(tile->flags & TF_BRAM_COL)) {
if ((rc = add_conn_bi(model, y, x, "NN2E0", y+1, x, "IOI_BTERM_NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y, x, "NN2E_S0", y+1, x, "IOI_BTERM_NN2M0"))) goto xout;
}
}
}
continue;
}
if (!(tile->flags & TF_DIRWIRE_START))
continue;
for (i = 0; i <= 3; i++) {
sprintf(b_wire, "NN2B%i", i);
sprintf(m_wire, "NN2M%i", i);
@ -325,13 +398,10 @@ int run_wires(struct fpga_model* model)
sprintf(r1e_wire, "NR1E%i", i);
if (tile_up1->flags & TF_UNDER_TOPMOST_TILE) {
if ((rc = add_conn_bi(model, y, x, b_wire, y-1, x, pf("IOI_TTERM_%s", b_wire)))) goto xout;
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-1, x, pf("IOI_TTERM_%s", r1b_wire)))) goto xout;
} else if (tile_up2->flags & TF_UNDER_TOPMOST_TILE) {
if ((rc = add_conn_bi(model, y, x, b_wire, y-1, x, m_wire))) goto xout;
if ((rc = add_conn_bi(model, y, x, b_wire, y-2, x, pf("IOI_TTERM_%s", m_wire)))) goto xout;
if ((rc = add_conn_bi(model, y-1, x, m_wire, y-2, x, pf("IOI_TTERM_%s", m_wire)))) goto xout;
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-1, x, r1e_wire))) goto xout;
} else if (tile_up1->flags & (TF_ROW_HORIZ_AXSYMM|TF_CHIP_HORIZ_AXSYMM)) {
if (tile_up1->flags & TF_ROW_HORIZ_AXSYMM)
@ -348,9 +418,6 @@ int run_wires(struct fpga_model* model)
if ((rc = add_conn_bi(model, y-1, x, pf(wire_fmt, m_wire), y-3, x, e_wire))) goto xout;
if ((rc = add_conn_bi(model, y-2, x, m_wire, y-3, x, e_wire))) goto xout;
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-2, x, r1e_wire))) goto xout;
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-1, x, pf(wire_fmt, r1e_wire)))) goto xout;
} else if (tile_up2->flags & (TF_ROW_HORIZ_AXSYMM|TF_CHIP_HORIZ_AXSYMM)) {
if (tile_up2->flags & TF_ROW_HORIZ_AXSYMM)
@ -367,17 +434,10 @@ int run_wires(struct fpga_model* model)
if ((rc = add_conn_bi(model, y-1, x, m_wire, y-3, x, e_wire))) goto xout;
if ((rc = add_conn_bi(model, y-2, x, pf(wire_fmt, e_wire), y-3, x, e_wire))) goto xout;
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-1, x, r1e_wire))) goto xout;
} else {
if ((rc = add_conn_bi(model, y, x, b_wire, y-1, x, m_wire))) goto xout;
if ((rc = add_conn_bi(model, y, x, b_wire, y-2, x, e_wire))) goto xout;
if ((rc = add_conn_bi(model, y-1, x, m_wire, y-2, x, e_wire))) goto xout;
if (!i) {
if ((rc = add_conn_bi(model, y, x, "NN2B0", y-1, x, "NN2E_S0"))) goto xout;
if ((rc = add_conn_bi(model, y-2, x, "NN2E0", y-1, x, "NN2E_S0"))) goto xout;
}
if ((rc = add_conn_bi(model, y, x, r1b_wire, y-1, x, r1e_wire))) goto xout;
}
}
}
@ -460,6 +520,11 @@ int init_tiles(struct fpga_model* model)
for (k = model->cfg_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles (center row)
for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
tile_i0->flags |= TF_LOGIC_COL;
tile_i0[1].flags |= TF_LOGIC_COL;
}
start = ((k == model->cfg_rows-1 && (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M')) ? 2 : 0);
end = ((k == 0 && (model->cfg_columns[j] == 'L' || model->cfg_columns[j] == 'M')) ? 14 : 16);
for (l = start; l < end; l++) {
@ -536,6 +601,9 @@ int init_tiles(struct fpga_model* model)
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
tile_i0->flags |= TF_BRAM_COL;
tile_i0[1].flags |= TF_BRAM_COL;
tile_i0[2].flags |= TF_BRAM_COL;
if (l < 15) {
tile_i0->type = BRAM_ROUTING;
tile_i0->flags |= TF_DIRWIRE_START;
@ -568,6 +636,9 @@ int init_tiles(struct fpga_model* model)
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
tile_i0->flags |= TF_MACC_COL;
tile_i0[1].flags |= TF_MACC_COL;
tile_i0[2].flags |= TF_MACC_COL;
if (l < 15) {
tile_i0->type = ROUTING;
tile_i0->flags |= TF_DIRWIRE_START;
@ -600,15 +671,22 @@ int init_tiles(struct fpga_model* model)
// the top and bottom bufpll and reg routing.
fprintf(stderr, "Expecting LOGIC_XM after center but found '%c'\n", model->cfg_columns[j+1]);
}
// flag vertical axis of symmetry
for (y = 0; y < model->tile_y_range; y++)
model->tiles[y*model->tile_x_range + i + 3].flags |= TF_CHIP_VERT_AXSYMM;
left_side = 0;
for (k = model->cfg_rows-1; k >= 0; k--) {
row_top_y = 2 /* top IO tiles */ + (model->cfg_rows-1-k)*(8+1/*middle of row clock*/+8);
if (k<(model->cfg_rows/2)) row_top_y++; // middle system tiles
for (l = 0; l < 16; l++) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
tile_i0->flags |= TF_LOGIC_COL;
tile_i0[1].flags |= TF_LOGIC_COL;
if ((k < model->cfg_rows-1 || l >= 2) && (k || l<14)) {
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
if (l < 15) {
tile_i0->type = ROUTING;
tile_i0->flags |= TF_DIRWIRE_START;
@ -625,7 +703,6 @@ int init_tiles(struct fpga_model* model)
}
if (l == 7
|| (l == 8 && !(k%2))) { // even row, together with DCM
tile_i0 = &model->tiles[(row_top_y+(l<8?l:l+1))*tile_columns + i];
tile_i0->type = IO_ROUTING;
tile_i0->flags |= TF_DIRWIRE_START;
}
@ -689,10 +766,6 @@ int init_tiles(struct fpga_model* model)
model->tiles[center_row*tile_columns + i + 2].type = REGC_CMT;
model->tiles[center_row*tile_columns + i + 3].type = CENTER;
// flag vertical axis of symmetry
for (y = 0; y < model->tile_y_range; y++)
model->tiles[y*model->tile_x_range + i + 3].flags |= TF_CHIP_VERT_AXSYMM;
i += 4;
break;
default:

View File

@ -11,6 +11,7 @@
#include <stdint.h>
#include <assert.h>
#include <sys/stat.h>
#define MACRO_STR(arg) #arg
#define HASHARRAY_NUM_INDICES (256*256)
@ -131,6 +132,9 @@ enum fpga_tile_type
#define TF_CHIP_HORIZ_AXSYMM 0x0080
#define TF_CHIP_VERT_AXSYMM 0x0100
#define TF_VERT_ROUTING 0x0200
#define TF_LOGIC_COL 0x0400
#define TF_MACC_COL 0x0800
#define TF_BRAM_COL 0x1000
struct fpga_tile
{

View File

@ -17,6 +17,7 @@
int main(int argc, char** argv)
{
struct fpga_model model;
struct fpga_tile* tile;
int x, y;
if (fpga_build_model(&model, XC6SLX9_ROWS, XC6SLX9_COLUMNS,
@ -24,6 +25,7 @@ int main(int argc, char** argv)
goto fail;
printf("fpga_floorplan_format 1\n");
//
// What needs to be in the file:
// - all devices, configuration for each device
@ -40,12 +42,71 @@ int main(int argc, char** argv)
// - file should be easily parsable with bison
// - lines should typically not exceed 80 characters
//
for (y = 0; y < model.tile_y_range; y++) {
for (x = 0; x < model.tile_x_range; x++) {
printf("y%i x%i %s\n", y, x,
fpga_tiletype_str(model.tiles[y*model.tile_x_range + x].type));
for (x = 0; x < model.tile_x_range; x++) {
printf("\n");
for (y = 0; y < model.tile_y_range; y++) {
tile = &model.tiles[y*model.tile_x_range + x];
printf("tile y%02i x%02i", y, x);
if (tile->type == NA && !(tile->flags)) {
printf(" -\n");
continue;
}
if (tile->type != NA)
printf(" name %s", fpga_tiletype_str(tile->type));
if (tile->flags) {
int tf = tile->flags;
printf(" flags");
if (tf & TF_DIRWIRE_START) {
printf(" %s", MACRO_STR(TF_DIRWIRE_START));
tf &= ~TF_DIRWIRE_START;
}
if (tf & TF_TOPMOST_TILE) {
printf(" %s", MACRO_STR(TF_TOPMOST_TILE));
tf &= ~TF_TOPMOST_TILE;
}
if (tf & TF_UNDER_TOPMOST_TILE) {
printf(" %s", MACRO_STR(TF_UNDER_TOPMOST_TILE));
tf &= ~TF_UNDER_TOPMOST_TILE;
}
if (tf & TF_ABOVE_BOTTOMMOST_TILE) {
printf(" %s", MACRO_STR(TF_ABOVE_BOTTOMMOST_TILE));
tf &= ~TF_ABOVE_BOTTOMMOST_TILE;
}
if (tf & TF_BOTTOMMOST_TILE) {
printf(" %s", MACRO_STR(TF_BOTTOMMOST_TILE));
tf &= ~TF_BOTTOMMOST_TILE;
}
if (tf & TF_ROW_HORIZ_AXSYMM) {
printf(" %s", MACRO_STR(TF_ROW_HORIZ_AXSYMM));
tf &= ~TF_ROW_HORIZ_AXSYMM;
}
if (tf & TF_BOTTOM_OF_ROW) {
printf(" %s", MACRO_STR(TF_BOTTOM_OF_ROW));
tf &= ~TF_BOTTOM_OF_ROW;
}
if (tf & TF_CHIP_HORIZ_AXSYMM) {
printf(" %s", MACRO_STR(TF_CHIP_HORIZ_AXSYMM));
tf &= ~TF_CHIP_HORIZ_AXSYMM;
}
if (tf & TF_CHIP_VERT_AXSYMM) {
printf(" %s", MACRO_STR(TF_CHIP_VERT_AXSYMM));
tf &= ~TF_CHIP_VERT_AXSYMM;
}
if (tf & TF_VERT_ROUTING) {
printf(" %s", MACRO_STR(TF_VERT_ROUTING));
tf &= ~TF_VERT_ROUTING;
}
if (tf)
printf(" 0x%x", tf);
}
printf("\n");
}
}
// todo: static_conn y%02i-x%02i-name y%02i-x%02i-name
// todo: static_net <lists all wires connected together statically in a long line>
return EXIT_SUCCESS;
fail: