VPR-6.0
|
00001 /** 00002 * @file 00003 * Author: Jason Luu 00004 * Date: October 8, 2008 00005 * 00006 * Initializes and allocates the physical logic block grid for VPR. 00007 */ 00008 00009 #include <string.h> 00010 #include <stdio.h> 00011 #include <assert.h> 00012 #include "util.h" 00013 #include "vpr_types.h" 00014 #include "globals.h" 00015 #include "SetupGrid.h" 00016 #include "read_xml_arch_file.h" 00017 00018 static void CheckGrid(void); 00019 static t_type_ptr find_type_col(INP int x); 00020 00021 00022 /** Create and fill FPGA architecture grid. */ 00023 void 00024 alloc_and_load_grid(INOUTP int *num_instances_type) 00025 { 00026 00027 int i, j; 00028 t_type_ptr type; 00029 00030 #ifdef SHOW_ARCH 00031 FILE *dump; 00032 #endif 00033 00034 00035 /* To remove this limitation, change ylow etc. in t_rr_node to * 00036 * * be ints instead. Used shorts to save memory. */ 00037 if((nx > 32766) || (ny > 32766)) 00038 { 00039 printf("Error: nx and ny must be less than 32767, since the \n"); 00040 printf("router uses shorts (16-bit) to store coordinates.\n"); 00041 printf("nx: %d. ny: %d.\n", nx, ny); 00042 exit(1); 00043 } 00044 00045 assert(nx >= 1 && ny >= 1); 00046 00047 grid = (struct s_grid_tile **)alloc_matrix(0, (nx + 1), 00048 0, (ny + 1), 00049 sizeof(struct s_grid_tile)); 00050 00051 /* Clear the full grid to have no type (NULL), no capacity, etc */ 00052 for(i = 0; i <= (nx + 1); ++i) 00053 { 00054 for(j = 0; j <= (ny + 1); ++j) 00055 { 00056 memset(&grid[i][j], 0, (sizeof(struct s_grid_tile))); 00057 } 00058 } 00059 00060 for(i = 0; i < num_types; i++) 00061 { 00062 num_instances_type[i] = 0; 00063 } 00064 00065 /* Nothing goes in the corners. */ 00066 grid[0][0].type = grid[nx + 1][0].type = EMPTY_TYPE; 00067 grid[0][ny + 1].type = grid[nx + 1][ny + 1].type = EMPTY_TYPE; 00068 num_instances_type[EMPTY_TYPE->index] = 4; 00069 00070 for(i = 1; i <= nx; i++) 00071 { 00072 grid[i][0].blocks = 00073 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00074 grid[i][0].type = IO_TYPE; 00075 00076 grid[i][ny + 1].blocks = 00077 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00078 grid[i][ny + 1].type = IO_TYPE; 00079 00080 for(j = 0; j < IO_TYPE->capacity; j++) 00081 { 00082 grid[i][0].blocks[j] = EMPTY; 00083 grid[i][ny + 1].blocks[j] = EMPTY; 00084 } 00085 } 00086 00087 for(i = 1; i <= ny; i++) 00088 { 00089 grid[0][i].blocks = 00090 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00091 grid[0][i].type = IO_TYPE; 00092 00093 grid[nx + 1][i].blocks = 00094 (int *)my_malloc(sizeof(int) * IO_TYPE->capacity); 00095 grid[nx + 1][i].type = IO_TYPE; 00096 for(j = 0; j < IO_TYPE->capacity; j++) 00097 { 00098 grid[0][i].blocks[j] = EMPTY; 00099 grid[nx + 1][i].blocks[j] = EMPTY; 00100 } 00101 } 00102 00103 num_instances_type[IO_TYPE->index] = 2 * IO_TYPE->capacity * (nx + ny); 00104 00105 for(i = 1; i <= nx; i++) 00106 { /* Interior (LUT) cells */ 00107 type = find_type_col(i); 00108 for(j = 1; j <= ny; j++) 00109 { 00110 grid[i][j].type = type; 00111 grid[i][j].offset = (j - 1) % type->height; 00112 if(j + grid[i][j].type->height - 1 - grid[i][j].offset > 00113 ny) 00114 { 00115 grid[i][j].type = EMPTY_TYPE; 00116 grid[i][j].offset = 0; 00117 } 00118 00119 if(type->capacity > 1) 00120 { 00121 printf(ERRTAG 00122 "In FillArch() expected core blocks to have capacity <= 1 but " 00123 "(%d, %d) has type '%s' and capacity %d\n", 00124 i, j, grid[i][j].type->name, 00125 grid[i][j].type->capacity); 00126 exit(1); 00127 } 00128 00129 grid[i][j].blocks = (int *)my_malloc(sizeof(int)); 00130 grid[i][j].blocks[0] = EMPTY; 00131 if(grid[i][j].offset == 0) 00132 { 00133 num_instances_type[grid[i][j].type->index]++; 00134 } 00135 } 00136 } 00137 00138 CheckGrid(); 00139 00140 #ifdef SHOW_ARCH 00141 /* DEBUG code */ 00142 dump = my_fopen("grid_type_dump.txt", "w", 0); 00143 for(j = (ny + 1); j >= 0; --j) 00144 { 00145 for(i = 0; i <= (nx + 1); ++i) 00146 { 00147 fprintf(dump, "%c", grid[i][j].type->name[1]); 00148 } 00149 fprintf(dump, "\n"); 00150 } 00151 fclose(dump); 00152 #endif 00153 } 00154 00155 void 00156 freeGrid() 00157 { 00158 int i, j; 00159 00160 for(i = 0; i <= (nx + 1); ++i) 00161 { 00162 for(j = 0; j <= (ny + 1); ++j) 00163 { 00164 free(grid[i][j].blocks); 00165 } 00166 } 00167 free_matrix(grid, 0, nx + 1, 0, sizeof(struct s_grid_tile)); 00168 } 00169 00170 00171 static void 00172 CheckGrid() 00173 { 00174 int i, j; 00175 00176 /* Check grid is valid */ 00177 for(i = 0; i <= (nx + 1); ++i) 00178 { 00179 for(j = 0; j <= (ny + 1); ++j) 00180 { 00181 if(NULL == grid[i][j].type) 00182 { 00183 printf(ERRTAG "grid[%d][%d] has no type.\n", i, 00184 j); 00185 exit(1); 00186 } 00187 00188 if(grid[i][j].usage != 0) 00189 { 00190 printf(ERRTAG 00191 "grid[%d][%d] has non-zero usage (%d) " 00192 "before netlist load.\n", i, j, 00193 grid[i][j].usage); 00194 exit(1); 00195 } 00196 00197 if((grid[i][j].offset < 0) || 00198 (grid[i][j].offset >= grid[i][j].type->height)) 00199 { 00200 printf(ERRTAG 00201 "grid[%d][%d] has invalid offset (%d)\n", 00202 i, j, grid[i][j].offset); 00203 exit(1); 00204 } 00205 00206 if((NULL == grid[i][j].blocks) && 00207 (grid[i][j].type->capacity > 0)) 00208 { 00209 printf(ERRTAG 00210 "grid[%d][%d] has no block list allocated.\n", 00211 i, j); 00212 exit(1); 00213 } 00214 } 00215 } 00216 } 00217 00218 static t_type_ptr 00219 find_type_col(INP int x) 00220 { 00221 int i, j; 00222 int start, repeat; 00223 float rel; 00224 boolean match; 00225 int priority, num_loc; 00226 t_type_ptr column_type; 00227 00228 priority = FILL_TYPE->grid_loc_def[0].priority; 00229 column_type = FILL_TYPE; 00230 00231 for(i = 0; i < num_types; i++) 00232 { 00233 if(&type_descriptors[i] == IO_TYPE || 00234 &type_descriptors[i] == EMPTY_TYPE || 00235 &type_descriptors[i] == FILL_TYPE) 00236 continue; 00237 num_loc = type_descriptors[i].num_grid_loc_def; 00238 for(j = 0; j < num_loc; j++) 00239 { 00240 if(priority < 00241 type_descriptors[i].grid_loc_def[j].priority) 00242 { 00243 match = FALSE; 00244 if(type_descriptors[i].grid_loc_def[j]. 00245 grid_loc_type == COL_REPEAT) 00246 { 00247 start = 00248 type_descriptors[i].grid_loc_def[j]. 00249 start_col; 00250 repeat = 00251 type_descriptors[i].grid_loc_def[j]. 00252 repeat; 00253 if(start < 0) 00254 { 00255 start += (nx + 1); 00256 } 00257 if(x == start) 00258 { 00259 match = TRUE; 00260 } 00261 else if(repeat > 0 && x > start 00262 && start > 0) 00263 { 00264 if((x - start) % repeat == 0) 00265 { 00266 match = TRUE; 00267 } 00268 } 00269 } 00270 else if(type_descriptors[i].grid_loc_def[j]. 00271 grid_loc_type == COL_REL) 00272 { 00273 rel = 00274 type_descriptors[i].grid_loc_def[j]. 00275 col_rel; 00276 if(nint(rel * nx) == x) 00277 { 00278 match = TRUE; 00279 } 00280 } 00281 if(match) 00282 { 00283 priority = 00284 type_descriptors[i].grid_loc_def[j]. 00285 priority; 00286 column_type = &type_descriptors[i]; 00287 } 00288 } 00289 } 00290 } 00291 return column_type; 00292 }