|
VPR-6.0
|
#include <string.h>#include <stdio.h>#include <assert.h>#include "util.h"#include "vpr_types.h"#include "globals.h"#include "SetupGrid.h"#include "read_xml_arch_file.h"
Include dependency graph for SetupGrid.c:Go to the source code of this file.
Functions | |
| static void | CheckGrid (void) |
| static t_type_ptr | find_type_col (INP int x) |
| void | alloc_and_load_grid (INOUTP int *num_instances_type) |
| void | freeGrid () |
Author: Jason Luu Date: October 8, 2008
Initializes and allocates the physical logic block grid for VPR.
Definition in file SetupGrid.c.
| void alloc_and_load_grid | ( | INOUTP int * | num_instances_type | ) |
Create and fill FPGA architecture grid.
Definition at line 24 of file SetupGrid.c.
{
int i, j;
t_type_ptr type;
#ifdef SHOW_ARCH
FILE *dump;
#endif
/* To remove this limitation, change ylow etc. in t_rr_node to *
* * be ints instead. Used shorts to save memory. */
if((nx > 32766) || (ny > 32766))
{
printf("Error: nx and ny must be less than 32767, since the \n");
printf("router uses shorts (16-bit) to store coordinates.\n");
printf("nx: %d. ny: %d.\n", nx, ny);
exit(1);
}
assert(nx >= 1 && ny >= 1);
grid = (struct s_grid_tile **)alloc_matrix(0, (nx + 1),
0, (ny + 1),
sizeof(struct s_grid_tile));
/* Clear the full grid to have no type (NULL), no capacity, etc */
for(i = 0; i <= (nx + 1); ++i)
{
for(j = 0; j <= (ny + 1); ++j)
{
memset(&grid[i][j], 0, (sizeof(struct s_grid_tile)));
}
}
for(i = 0; i < num_types; i++)
{
num_instances_type[i] = 0;
}
/* Nothing goes in the corners. */
grid[0][0].type = grid[nx + 1][0].type = EMPTY_TYPE;
grid[0][ny + 1].type = grid[nx + 1][ny + 1].type = EMPTY_TYPE;
num_instances_type[EMPTY_TYPE->index] = 4;
for(i = 1; i <= nx; i++)
{
grid[i][0].blocks =
(int *)my_malloc(sizeof(int) * IO_TYPE->capacity);
grid[i][0].type = IO_TYPE;
grid[i][ny + 1].blocks =
(int *)my_malloc(sizeof(int) * IO_TYPE->capacity);
grid[i][ny + 1].type = IO_TYPE;
for(j = 0; j < IO_TYPE->capacity; j++)
{
grid[i][0].blocks[j] = EMPTY;
grid[i][ny + 1].blocks[j] = EMPTY;
}
}
for(i = 1; i <= ny; i++)
{
grid[0][i].blocks =
(int *)my_malloc(sizeof(int) * IO_TYPE->capacity);
grid[0][i].type = IO_TYPE;
grid[nx + 1][i].blocks =
(int *)my_malloc(sizeof(int) * IO_TYPE->capacity);
grid[nx + 1][i].type = IO_TYPE;
for(j = 0; j < IO_TYPE->capacity; j++)
{
grid[0][i].blocks[j] = EMPTY;
grid[nx + 1][i].blocks[j] = EMPTY;
}
}
num_instances_type[IO_TYPE->index] = 2 * IO_TYPE->capacity * (nx + ny);
for(i = 1; i <= nx; i++)
{ /* Interior (LUT) cells */
type = find_type_col(i);
for(j = 1; j <= ny; j++)
{
grid[i][j].type = type;
grid[i][j].offset = (j - 1) % type->height;
if(j + grid[i][j].type->height - 1 - grid[i][j].offset >
ny)
{
grid[i][j].type = EMPTY_TYPE;
grid[i][j].offset = 0;
}
if(type->capacity > 1)
{
printf(ERRTAG
"In FillArch() expected core blocks to have capacity <= 1 but "
"(%d, %d) has type '%s' and capacity %d\n",
i, j, grid[i][j].type->name,
grid[i][j].type->capacity);
exit(1);
}
grid[i][j].blocks = (int *)my_malloc(sizeof(int));
grid[i][j].blocks[0] = EMPTY;
if(grid[i][j].offset == 0)
{
num_instances_type[grid[i][j].type->index]++;
}
}
}
CheckGrid();
#ifdef SHOW_ARCH
/* DEBUG code */
dump = my_fopen("grid_type_dump.txt", "w", 0);
for(j = (ny + 1); j >= 0; --j)
{
for(i = 0; i <= (nx + 1); ++i)
{
fprintf(dump, "%c", grid[i][j].type->name[1]);
}
fprintf(dump, "\n");
}
fclose(dump);
#endif
}
Here is the call graph for this function:
Here is the caller graph for this function:| static void CheckGrid | ( | void | ) | [static] |
Definition at line 172 of file SetupGrid.c.
{
int i, j;
/* Check grid is valid */
for(i = 0; i <= (nx + 1); ++i)
{
for(j = 0; j <= (ny + 1); ++j)
{
if(NULL == grid[i][j].type)
{
printf(ERRTAG "grid[%d][%d] has no type.\n", i,
j);
exit(1);
}
if(grid[i][j].usage != 0)
{
printf(ERRTAG
"grid[%d][%d] has non-zero usage (%d) "
"before netlist load.\n", i, j,
grid[i][j].usage);
exit(1);
}
if((grid[i][j].offset < 0) ||
(grid[i][j].offset >= grid[i][j].type->height))
{
printf(ERRTAG
"grid[%d][%d] has invalid offset (%d)\n",
i, j, grid[i][j].offset);
exit(1);
}
if((NULL == grid[i][j].blocks) &&
(grid[i][j].type->capacity > 0))
{
printf(ERRTAG
"grid[%d][%d] has no block list allocated.\n",
i, j);
exit(1);
}
}
}
}
Here is the caller graph for this function:| static t_type_ptr find_type_col | ( | INP int | x | ) | [static] |
Definition at line 219 of file SetupGrid.c.
{
int i, j;
int start, repeat;
float rel;
boolean match;
int priority, num_loc;
t_type_ptr column_type;
priority = FILL_TYPE->grid_loc_def[0].priority;
column_type = FILL_TYPE;
for(i = 0; i < num_types; i++)
{
if(&type_descriptors[i] == IO_TYPE ||
&type_descriptors[i] == EMPTY_TYPE ||
&type_descriptors[i] == FILL_TYPE)
continue;
num_loc = type_descriptors[i].num_grid_loc_def;
for(j = 0; j < num_loc; j++)
{
if(priority <
type_descriptors[i].grid_loc_def[j].priority)
{
match = FALSE;
if(type_descriptors[i].grid_loc_def[j].
grid_loc_type == COL_REPEAT)
{
start =
type_descriptors[i].grid_loc_def[j].
start_col;
repeat =
type_descriptors[i].grid_loc_def[j].
repeat;
if(start < 0)
{
start += (nx + 1);
}
if(x == start)
{
match = TRUE;
}
else if(repeat > 0 && x > start
&& start > 0)
{
if((x - start) % repeat == 0)
{
match = TRUE;
}
}
}
else if(type_descriptors[i].grid_loc_def[j].
grid_loc_type == COL_REL)
{
rel =
type_descriptors[i].grid_loc_def[j].
col_rel;
if(nint(rel * nx) == x)
{
match = TRUE;
}
}
if(match)
{
priority =
type_descriptors[i].grid_loc_def[j].
priority;
column_type = &type_descriptors[i];
}
}
}
}
return column_type;
}
Here is the caller graph for this function:| void freeGrid | ( | ) |
Definition at line 156 of file SetupGrid.c.
{
int i, j;
for(i = 0; i <= (nx + 1); ++i)
{
for(j = 0; j <= (ny + 1); ++j)
{
free(grid[i][j].blocks);
}
}
free_matrix(grid, 0, nx + 1, 0, sizeof(struct s_grid_tile));
}
Here is the call graph for this function:
Here is the caller graph for this function: