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"
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 }
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); } } } }
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; }
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)); }