VPR-6.0

vpr/SRC/base/SetupGrid.c

Go to the documentation of this file.
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 }