VPR-6.0

vpr/SRC/util/vpr_utils.c

Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <string.h>
00003 #include "util.h"
00004 #include "vpr_types.h"
00005 #include "globals.h"
00006 #include "vpr_utils.h"
00007 
00008 /**
00009  * @file
00010  *
00011  * This module contains subroutines that are used in several unrelated parts 
00012  * of VPR.  They are VPR-specific utility routines.                          
00013  */
00014 
00015 /******************** Subroutine definitions ********************************/
00016 
00017 /**
00018  * print tabs given number of tabs to file
00019  */
00020 void
00021 print_tabs(FILE * fpout, int num_tab) {
00022         int i;
00023         for(i = 0; i < num_tab; i++) {
00024                 fprintf(fpout, "\t");
00025         }
00026 }
00027 
00028 
00029 /** Points the grid structure back to the blocks list */
00030 void
00031 sync_grid_to_blocks(INP int num_blocks,
00032                     INP const struct s_block block_list[],
00033                     INP int nx,
00034                     INP int ny,
00035                     INOUTP struct s_grid_tile **grid)
00036 {
00037     int i, j, k;
00038 
00039     /* Reset usage and allocate blocks list if needed */
00040     for(j = 0; j <= (ny + 1); ++j)
00041         {
00042             for(i = 0; i <= (nx + 1); ++i)
00043                 {
00044                     grid[i][j].usage = 0;
00045                     if(grid[i][j].type)
00046                         {
00047                             /* If already allocated, leave it since size doesn't change */
00048                             if(NULL == grid[i][j].blocks)
00049                                 {
00050                                     grid[i][j].blocks =
00051                                         (int *)my_malloc(sizeof(int) *
00052                                                          grid[i][j].type->
00053                                                          capacity);
00054 
00055                                     /* Set them as unconnected */
00056                                     for(k = 0; k < grid[i][j].type->capacity;
00057                                         ++k)
00058                                         {
00059                                             grid[i][j].blocks[k] = OPEN;
00060                                         }
00061                                 }
00062                         }
00063                 }
00064         }
00065 
00066     /* Go through each block */
00067     for(i = 0; i < num_blocks; ++i)
00068         {
00069             /* Check range of block coords */
00070             if(block[i].x < 0 || block[i].x > (nx + 1) ||
00071                block[i].y < 0
00072                || (block[i].y + block[i].type->height - 1) > (ny + 1)
00073                || block[i].z < 0 || block[i].z > (block[i].type->capacity))
00074                 {
00075                     printf(ERRTAG
00076                            "Block %d is at invalid location (%d, %d, %d)\n",
00077                            i, block[i].x, block[i].y, block[i].z);
00078                     exit(1);
00079                 }
00080 
00081             /* Check types match */
00082             if(block[i].type != grid[block[i].x][block[i].y].type)
00083                 {
00084                     printf(ERRTAG "A block is in a grid location "
00085                            "(%d x %d) with a conflicting type.\n", block[i].x,
00086                            block[i].y);
00087                     exit(1);
00088                 }
00089 
00090             /* Check already in use */
00091             if(OPEN != grid[block[i].x][block[i].y].blocks[block[i].z])
00092                 {
00093                     printf(ERRTAG
00094                            "Location (%d, %d, %d) is used more than once\n",
00095                            block[i].x, block[i].y, block[i].z);
00096                     exit(1);
00097                 }
00098 
00099             if(grid[block[i].x][block[i].y].offset != 0)
00100                 {
00101                     printf(ERRTAG
00102                            "Large block not aligned in placment for block %d at (%d, %d, %d)",
00103                            i, block[i].x, block[i].y, block[i].z);
00104                     exit(1);
00105                 }
00106 
00107             /* Set the block */
00108             for(j = 0; j < block[i].type->height; j++)
00109                 {
00110                     grid[block[i].x][block[i].y + j].blocks[block[i].z] = i;
00111                     grid[block[i].x][block[i].y + j].usage++;
00112                     assert(grid[block[i].x][block[i].y + j].offset == j);
00113                 }
00114         }
00115 }
00116 
00117 
00118 /** Returns TRUE if this clb pin is an output, FALSE otherwise. */
00119 boolean
00120 is_opin(int ipin,
00121         t_type_ptr type)
00122 {
00123     int iclass;
00124 
00125     iclass = type->pin_class[ipin];
00126 
00127     if(type->class_inf[iclass].type == DRIVER)
00128         return (TRUE);
00129     else
00130         return (FALSE);
00131 }
00132 
00133 /** Assumes that the placement has been done so each block has a set of pins allocated to it */
00134 void
00135 get_class_range_for_block(INP int iblk,
00136                           OUTP int *class_low,
00137                           OUTP int *class_high)
00138 {
00139     t_type_ptr type;
00140 
00141     type = block[iblk].type;
00142     assert(type->num_class % type->capacity == 0);
00143     *class_low = block[iblk].z * (type->num_class / type->capacity);
00144     *class_high =
00145         (block[iblk].z + 1) * (type->num_class / type->capacity) - 1;
00146 }