#include <assert.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "vpr_utils.h"
Go to the source code of this file.
Functions | |
void | sync_grid_to_blocks (IN int num_blocks, IN const struct s_block block_list[], IN int nx, IN int ny, INOUT struct s_grid_tile **grid) |
void | sync_nets_to_blocks (IN int num_blocks, IN const struct s_block block_list[], IN int num_nets, INOUT struct s_net net_list[]) |
boolean | is_opin (int ipin, t_type_ptr type) |
void | get_class_range_for_block (IN int iblk, OUT int *class_low, OUT int *class_high) |
void | load_one_fb_fanout_count (t_subblock *subblock_inf, int num_subblocks, int *num_uses_of_fb_ipin, int **num_uses_of_sblk_opin, int iblk) |
void get_class_range_for_block | ( | IN int | iblk, | |
OUT int * | class_low, | |||
OUT int * | class_high | |||
) |
Definition at line 200 of file vpr_utils.c.
00203 { 00204 /* Assumes that the placement has been done so each block has a set of pins allocated to it */ 00205 t_type_ptr type; 00206 00207 type = block[iblk].type; 00208 assert(type->num_class % type->capacity == 0); 00209 *class_low = block[iblk].z * (type->num_class / type->capacity); 00210 *class_high = 00211 (block[iblk].z + 1) * (type->num_class / type->capacity) - 1; 00212 }
boolean is_opin | ( | int | ipin, | |
t_type_ptr | type | |||
) |
Definition at line 183 of file vpr_utils.c.
00185 { 00186 00187 /* Returns TRUE if this clb pin is an output, FALSE otherwise. */ 00188 00189 int iclass; 00190 00191 iclass = type->pin_class[ipin]; 00192 00193 if(type->class_inf[iclass].type == DRIVER) 00194 return (TRUE); 00195 else 00196 return (FALSE); 00197 }
void load_one_fb_fanout_count | ( | t_subblock * | subblock_inf, | |
int | num_subblocks, | |||
int * | num_uses_of_fb_ipin, | |||
int ** | num_uses_of_sblk_opin, | |||
int | iblk | |||
) |
Definition at line 216 of file vpr_utils.c.
00221 { 00222 00223 /* Loads the fanout counts for one block (iblk). */ 00224 t_type_ptr type = block[iblk].type; 00225 int isub, ipin, conn_pin, opin; 00226 int internal_sub, internal_pin; 00227 00228 /* Reset ipin counts */ 00229 for(ipin = 0; ipin < type->num_pins; ipin++) 00230 { 00231 num_uses_of_fb_ipin[ipin] = 0; 00232 } 00233 00234 /* First pass, reset fanout counts */ 00235 for(isub = 0; isub < num_subblocks; isub++) 00236 { 00237 for(opin = 0; opin < type->max_subblock_outputs; opin++) 00238 { 00239 num_uses_of_sblk_opin[isub][opin] = 0; 00240 } 00241 } 00242 00243 for(isub = 0; isub < num_subblocks; isub++) 00244 { 00245 /* Is the subblock output connected to a FB opin that actually goes * 00246 * somewhere? Necessary to check that the FB opin connects to * 00247 * something because some logic blocks result in netlists where * 00248 * subblock outputs being automatically hooked to a FB opin under * 00249 * all conditions. */ 00250 for(opin = 0; opin < type->max_subblock_outputs; opin++) 00251 { 00252 conn_pin = subblock_inf[isub].outputs[opin]; 00253 if(conn_pin != OPEN) 00254 { 00255 if(block[iblk].nets[conn_pin] != OPEN) 00256 { /* FB output is used */ 00257 num_uses_of_sblk_opin[isub][opin]++; 00258 } 00259 } 00260 } 00261 00262 for(ipin = 0; ipin < type->max_subblock_inputs; ipin++) 00263 { 00264 conn_pin = subblock_inf[isub].inputs[ipin]; 00265 00266 if(conn_pin != OPEN) 00267 { 00268 if(conn_pin < type->num_pins) 00269 { /* Driven by FB ipin */ 00270 num_uses_of_fb_ipin[conn_pin]++; 00271 } 00272 else 00273 { /* Driven by sblk output in same fb */ 00274 internal_sub = 00275 (conn_pin - 00276 type->num_pins) / 00277 type->max_subblock_outputs; 00278 internal_pin = 00279 (conn_pin - 00280 type->num_pins) % 00281 type->max_subblock_outputs; 00282 num_uses_of_sblk_opin[internal_sub] 00283 [internal_pin]++; 00284 } 00285 } 00286 } /* End for each sblk ipin */ 00287 00288 conn_pin = subblock_inf[isub].clock; /* Now do clock pin */ 00289 00290 if(conn_pin != OPEN) 00291 { 00292 if(conn_pin < type->num_pins) 00293 { /* Driven by FB ipin */ 00294 num_uses_of_fb_ipin[conn_pin]++; 00295 } 00296 else 00297 { /* Driven by sblk output in same clb */ 00298 internal_sub = 00299 (conn_pin - 00300 type->num_pins) / type->max_subblock_outputs; 00301 internal_pin = 00302 (conn_pin - 00303 type->num_pins) % type->max_subblock_outputs; 00304 num_uses_of_sblk_opin[internal_sub] 00305 [internal_pin]++; 00306 } 00307 } 00308 00309 } /* End for each subblock */ 00310 }
void sync_grid_to_blocks | ( | IN int | num_blocks, | |
IN const struct s_block | block_list[], | |||
IN int | nx, | |||
IN int | ny, | |||
INOUT struct s_grid_tile ** | grid | |||
) |
Definition at line 15 of file vpr_utils.c.
00020 { 00021 int i, j, k; 00022 00023 /* Reset usage and allocate blocks list if needed */ 00024 for(j = 0; j <= (ny + 1); ++j) 00025 { 00026 for(i = 0; i <= (nx + 1); ++i) 00027 { 00028 grid[i][j].usage = 0; 00029 if(grid[i][j].type) 00030 { 00031 /* If already allocated, leave it since size doesn't change */ 00032 if(NULL == grid[i][j].blocks) 00033 { 00034 grid[i][j].blocks = 00035 (int *)my_malloc(sizeof(int) * 00036 grid[i][j].type-> 00037 capacity); 00038 00039 /* Set them as unconnected */ 00040 for(k = 0; k < grid[i][j].type->capacity; 00041 ++k) 00042 { 00043 grid[i][j].blocks[k] = OPEN; 00044 } 00045 } 00046 } 00047 } 00048 } 00049 00050 /* Go through each block */ 00051 for(i = 0; i < num_blocks; ++i) 00052 { 00053 /* Check range of block coords */ 00054 if(block[i].x < 0 || block[i].x > (nx + 1) || 00055 block[i].y < 0 00056 || (block[i].y + block[i].type->height - 1) > (ny + 1) 00057 || block[i].z < 0 || block[i].z > (block[i].type->capacity)) 00058 { 00059 printf(ERRTAG 00060 "Block %d is at invalid location (%d, %d, %d)\n", 00061 i, block[i].x, block[i].y, block[i].z); 00062 exit(1); 00063 } 00064 00065 /* Check types match */ 00066 if(block[i].type != grid[block[i].x][block[i].y].type) 00067 { 00068 printf(ERRTAG "A block is in a grid location " 00069 "(%d x %d) with a conflicting type.\n", block[i].x, 00070 block[i].y); 00071 exit(1); 00072 } 00073 00074 /* Check already in use */ 00075 if(OPEN != grid[block[i].x][block[i].y].blocks[block[i].z]) 00076 { 00077 printf(ERRTAG 00078 "Location (%d, %d, %d) is used more than once\n", 00079 block[i].x, block[i].y, block[i].z); 00080 exit(1); 00081 } 00082 00083 if(grid[block[i].x][block[i].y].offset != 0) 00084 { 00085 printf(ERRTAG 00086 "Large block not aligned in placment for block %d at (%d, %d, %d)", 00087 i, block[i].x, block[i].y, block[i].z); 00088 exit(1); 00089 } 00090 00091 /* Set the block */ 00092 for(j = 0; j < block[i].type->height; j++) 00093 { 00094 grid[block[i].x][block[i].y + j].blocks[block[i].z] = i; 00095 grid[block[i].x][block[i].y + j].usage++; 00096 assert(grid[block[i].x][block[i].y + j].offset == j); 00097 } 00098 } 00099 }
void sync_nets_to_blocks | ( | IN int | num_blocks, | |
IN const struct s_block | block_list[], | |||
IN int | num_nets, | |||
INOUT struct s_net | net_list[] | |||
) |
Definition at line 103 of file vpr_utils.c.
00107 { 00108 int i, j, k, l; 00109 t_type_ptr cur_type; 00110 00111 /* Count the number of sinks for each net */ 00112 for(i = 0; i < num_nets; ++i) 00113 { 00114 for(j = 0; j < num_blocks; ++j) 00115 { 00116 cur_type = block_list[j].type; 00117 for(k = 0; k < cur_type->num_pins; ++k) 00118 { 00119 if(block_list[j].nets[k] == i) 00120 { 00121 if(RECEIVER == 00122 cur_type->class_inf[cur_type-> 00123 pin_class[k]].type) 00124 { 00125 ++net_list[i].num_sinks; 00126 } 00127 } 00128 } 00129 } 00130 } 00131 00132 /* Alloc and load block lists of nets */ 00133 for(i = 0; i < num_nets; ++i) 00134 { 00135 /* The list should be num_sinks + 1 driver. Re-alloc if already allocated. */ 00136 if(net_list[i].node_block) 00137 { 00138 free(net_list[i].node_block); 00139 } 00140 net_list[i].node_block = 00141 (int *)my_malloc(sizeof(int) * (net_list[i].num_sinks + 1)); 00142 if(net_list[i].node_block_pin) 00143 { 00144 free(net_list[i].node_block_pin); 00145 } 00146 net_list[i].node_block_pin = 00147 (int *)my_malloc(sizeof(int) * (net_list[i].num_sinks + 1)); 00148 00149 l = 1; /* First sink goes at position 1, since 0 is for driver */ 00150 00151 for(j = 0; j < num_blocks; ++j) 00152 { 00153 cur_type = block_list[j].type; 00154 for(k = 0; k < cur_type->num_pins; ++k) 00155 { 00156 if(block_list[j].nets[k] == i) 00157 { 00158 if(RECEIVER == 00159 cur_type->class_inf[cur_type-> 00160 pin_class[k]].type) 00161 { 00162 net_list[i].node_block[l] = j; 00163 net_list[i].node_block_pin[l] = k; 00164 ++l; 00165 } 00166 else 00167 { 00168 assert(DRIVER == 00169 cur_type-> 00170 class_inf[cur_type-> 00171 pin_class[k]]. 00172 type); 00173 net_list[i].node_block[0] = j; 00174 net_list[i].node_block_pin[0] = k; 00175 } 00176 } 00177 } 00178 } 00179 } 00180 }