VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
SetupGrid.c
Go to the documentation of this file.
1 /*
2  Author: Jason Luu
3  Date: October 8, 2008
4 
5  Initializes and allocates the physical logic block grid for VPR.
6 
7  */
8 
9 #include <string.h>
10 #include <stdio.h>
11 #include <assert.h>
12 #include "util.h"
13 #include "vpr_types.h"
14 #include "globals.h"
15 #include "SetupGrid.h"
16 #include "read_xml_arch_file.h"
17 
18 static void CheckGrid(void);
19 static t_type_ptr find_type_col(INP int x);
20 
21 /* Create and fill FPGA architecture grid. */
22 void alloc_and_load_grid(INOUTP int *num_instances_type) {
23 
24  int i, j;
25  t_type_ptr type;
26 
27 #ifdef SHOW_ARCH
28  FILE *dump;
29 #endif
30 
31  /* To remove this limitation, change ylow etc. in t_rr_node to *
32  * * be ints instead. Used shorts to save memory. */
33  if ((nx > 32766) || (ny > 32766)) {
34  vpr_printf(TIO_MESSAGE_ERROR, "nx and ny must be less than 32767, since the router uses shorts (16-bit) to store coordinates.\n");
35  vpr_printf(TIO_MESSAGE_ERROR, "nx: %d, ny: %d\n", nx, ny);
36  exit(1);
37  }
38 
39  assert(nx >= 1 && ny >= 1);
40 
41  grid = (struct s_grid_tile **) alloc_matrix(0, (nx + 1), 0, (ny + 1),
42  sizeof(struct s_grid_tile));
43 
44  /* Clear the full grid to have no type (NULL), no capacity, etc */
45  for (i = 0; i <= (nx + 1); ++i) {
46  for (j = 0; j <= (ny + 1); ++j) {
47  memset(&grid[i][j], 0, (sizeof(struct s_grid_tile)));
48  }
49  }
50 
51  for (i = 0; i < num_types; i++) {
52  num_instances_type[i] = 0;
53  }
54 
55  /* Nothing goes in the corners. */
56  grid[0][0].type = grid[nx + 1][0].type = EMPTY_TYPE;
57  grid[0][ny + 1].type = grid[nx + 1][ny + 1].type = EMPTY_TYPE;
58  num_instances_type[EMPTY_TYPE->index] = 4;
59 
60  for (i = 1; i <= nx; i++) {
61  grid[i][0].blocks = (int *) my_malloc(sizeof(int) * IO_TYPE->capacity);
62  grid[i][0].type = IO_TYPE;
63 
64  grid[i][ny + 1].blocks = (int *) my_malloc(
65  sizeof(int) * IO_TYPE->capacity);
66  grid[i][ny + 1].type = IO_TYPE;
67 
68  for (j = 0; j < IO_TYPE->capacity; j++) {
69  grid[i][0].blocks[j] = EMPTY;
70  grid[i][ny + 1].blocks[j] = EMPTY;
71  }
72  }
73 
74  for (i = 1; i <= ny; i++) {
75  grid[0][i].blocks = (int *) my_malloc(sizeof(int) * IO_TYPE->capacity);
76  grid[0][i].type = IO_TYPE;
77 
78  grid[nx + 1][i].blocks = (int *) my_malloc(
79  sizeof(int) * IO_TYPE->capacity);
80  grid[nx + 1][i].type = IO_TYPE;
81  for (j = 0; j < IO_TYPE->capacity; j++) {
82  grid[0][i].blocks[j] = EMPTY;
83  grid[nx + 1][i].blocks[j] = EMPTY;
84  }
85  }
86 
87  num_instances_type[IO_TYPE->index] = 2 * IO_TYPE->capacity * (nx + ny);
88 
89  for (i = 1; i <= nx; i++) { /* Interior (LUT) cells */
90  type = find_type_col(i);
91  for (j = 1; j <= ny; j++) {
92  grid[i][j].type = type;
93  grid[i][j].offset = (j - 1) % type->height;
94  if (j + grid[i][j].type->height - 1 - grid[i][j].offset > ny) {
95  grid[i][j].type = EMPTY_TYPE;
96  grid[i][j].offset = 0;
97  }
98 
99  if (type->capacity > 1) {
100  vpr_printf(TIO_MESSAGE_ERROR, "in FillArch(), expected core blocks to have capacity <= 1 but (%d, %d) has type '%s' and capacity %d.\n",
101  i, j, grid[i][j].type->name, grid[i][j].type->capacity);
102  exit(1);
103  }
104 
105  grid[i][j].blocks = (int *) my_malloc(sizeof(int));
106  grid[i][j].blocks[0] = EMPTY;
107  if (grid[i][j].offset == 0) {
108  num_instances_type[grid[i][j].type->index]++;
109  }
110  }
111  }
112 
113  CheckGrid();
114 
115 #ifdef SHOW_ARCH
116  /* DEBUG code */
117  dump = my_fopen("grid_type_dump.txt", "w", 0);
118  for (j = (ny + 1); j >= 0; --j)
119  {
120  for (i = 0; i <= (nx + 1); ++i)
121  {
122  fprintf(dump, "%c", grid[i][j].type->name[1]);
123  }
124  fprintf(dump, "\n");
125  }
126  fclose(dump);
127 #endif
128 }
129 
130 void freeGrid() {
131  int i, j;
132  if (grid == NULL) {
133  return;
134  }
135 
136  for (i = 0; i <= (nx + 1); ++i) {
137  for (j = 0; j <= (ny + 1); ++j) {
138  free(grid[i][j].blocks);
139  }
140  }
141  free_matrix(grid, 0, nx + 1, 0, sizeof(struct s_grid_tile));
142  grid = NULL;
143 }
144 
145 static void CheckGrid() {
146  int i, j;
147 
148  /* Check grid is valid */
149  for (i = 0; i <= (nx + 1); ++i) {
150  for (j = 0; j <= (ny + 1); ++j) {
151  if (NULL == grid[i][j].type) {
152  vpr_printf(TIO_MESSAGE_ERROR, "grid[%d][%d] has no type.\n", i, j);
153  exit(1);
154  }
155 
156  if (grid[i][j].usage != 0) {
157  vpr_printf(TIO_MESSAGE_ERROR, "grid[%d][%d] has non-zero usage (%d) before netlist load.\n", i, j, grid[i][j].usage);
158  exit(1);
159  }
160 
161  if ((grid[i][j].offset < 0)
162  || (grid[i][j].offset >= grid[i][j].type->height)) {
163  vpr_printf(TIO_MESSAGE_ERROR, "grid[%d][%d] has invalid offset (%d).\n", i, j, grid[i][j].offset);
164  exit(1);
165  }
166 
167  if ((NULL == grid[i][j].blocks)
168  && (grid[i][j].type->capacity > 0)) {
169  vpr_printf(TIO_MESSAGE_ERROR, "grid[%d][%d] has no block list allocated.\n", i, j);
170  exit(1);
171  }
172  }
173  }
174 }
175 
176 static t_type_ptr find_type_col(INP int x) {
177  int i, j;
178  int start, repeat;
179  float rel;
180  boolean match;
181  int priority, num_loc;
182  t_type_ptr column_type;
183 
184  priority = FILL_TYPE->grid_loc_def[0].priority;
185  column_type = FILL_TYPE;
186 
187  for (i = 0; i < num_types; i++) {
188  if (&type_descriptors[i] == IO_TYPE
189  || &type_descriptors[i] == EMPTY_TYPE
190  || &type_descriptors[i] == FILL_TYPE)
191  continue;
192  num_loc = type_descriptors[i].num_grid_loc_def;
193  for (j = 0; j < num_loc; j++) {
194  if (priority < type_descriptors[i].grid_loc_def[j].priority) {
195  match = FALSE;
196  if (type_descriptors[i].grid_loc_def[j].grid_loc_type
197  == COL_REPEAT) {
199  repeat = type_descriptors[i].grid_loc_def[j].repeat;
200  if (start < 0) {
201  start += (nx + 1);
202  }
203  if (x == start) {
204  match = TRUE;
205  } else if (repeat > 0 && x > start && start > 0) {
206  if ((x - start) % repeat == 0) {
207  match = TRUE;
208  }
209  }
210  } else if (type_descriptors[i].grid_loc_def[j].grid_loc_type
211  == COL_REL) {
213  if (nint(rel * nx) == x) {
214  match = TRUE;
215  }
216  }
217  if (match) {
218  priority = type_descriptors[i].grid_loc_def[j].priority;
219  column_type = &type_descriptors[i];
220  }
221  }
222  }
223  }
224  return column_type;
225 }
t_type_ptr type
Definition: vpr_types.h:522
t_type_ptr FILL_TYPE
Definition: globals.c:42
FILE * my_fopen(const char *fname, const char *flag, int prompt)
Definition: util.c:54
void ** alloc_matrix(int nrmin, int nrmax, int ncmin, int ncmax, size_t elsize)
Definition: util.c:551
void freeGrid()
Definition: SetupGrid.c:130
t_type_ptr EMPTY_TYPE
Definition: globals.c:41
void free_matrix(void *vptr, int nrmin, int nrmax, int ncmin, size_t elsize)
Definition: util.c:573
#define nint(a)
Definition: util.h:24
struct s_grid_loc_def * grid_loc_def
#define INOUTP
Definition: util.h:21
Definition: util.h:12
void alloc_and_load_grid(INOUTP int *num_instances_type)
Definition: SetupGrid.c:22
#define EMPTY
Definition: vpr_types.h:90
static void * my_malloc(int ibytes)
Definition: graphics.c:499
#define INP
Definition: util.h:19
int nx
Definition: globals.c:46
static void CheckGrid(void)
Definition: SetupGrid.c:145
struct s_grid_tile ** grid
Definition: globals.c:59
int * blocks
Definition: vpr_types.h:525
int num_types
Definition: globals.c:37
t_type_ptr IO_TYPE
Definition: globals.c:40
static t_type_ptr find_type_col(INP int x)
Definition: SetupGrid.c:176
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
int ny
Definition: globals.c:47
messagelogger vpr_printf
Definition: util.c:17
static const char * match(const struct slre *, int, const char *, int, int *, struct cap *)
Definition: slre.c:404
Definition: util.h:12