VPR-6.0
|
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 }