00001 #include <assert.h>
00002 #include "util.h"
00003 #include "vpr_types.h"
00004 #include "globals.h"
00005 #include "vpr_utils.h"
00006
00007
00008
00009
00010
00011
00012
00013
00014 void
00015 sync_grid_to_blocks(IN int num_blocks,
00016 IN const struct s_block block_list[],
00017 IN int nx,
00018 IN int ny,
00019 INOUT struct s_grid_tile **grid)
00020 {
00021 int i, j, k;
00022
00023
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
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
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
00051 for(i = 0; i < num_blocks; ++i)
00052 {
00053
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
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
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
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 }
00100
00101
00102 void
00103 sync_nets_to_blocks(IN int num_blocks,
00104 IN const struct s_block block_list[],
00105 IN int num_nets,
00106 INOUT struct s_net net_list[])
00107 {
00108 int i, j, k, l;
00109 t_type_ptr cur_type;
00110
00111
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
00133 for(i = 0; i < num_nets; ++i)
00134 {
00135
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;
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 }
00181
00182 boolean
00183 is_opin(int ipin,
00184 t_type_ptr type)
00185 {
00186
00187
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 }
00198
00199 void
00200 get_class_range_for_block(IN int iblk,
00201 OUT int *class_low,
00202 OUT int *class_high)
00203 {
00204
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 }
00213
00214
00215 void
00216 load_one_fb_fanout_count(t_subblock * subblock_inf,
00217 int num_subblocks,
00218 int *num_uses_of_fb_ipin,
00219 int **num_uses_of_sblk_opin,
00220 int iblk)
00221 {
00222
00223
00224 t_type_ptr type = block[iblk].type;
00225 int isub, ipin, conn_pin, opin;
00226 int internal_sub, internal_pin;
00227
00228
00229 for(ipin = 0; ipin < type->num_pins; ipin++)
00230 {
00231 num_uses_of_fb_ipin[ipin] = 0;
00232 }
00233
00234
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
00246
00247
00248
00249
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 {
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 {
00270 num_uses_of_fb_ipin[conn_pin]++;
00271 }
00272 else
00273 {
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 }
00287
00288 conn_pin = subblock_inf[isub].clock;
00289
00290 if(conn_pin != OPEN)
00291 {
00292 if(conn_pin < type->num_pins)
00293 {
00294 num_uses_of_fb_ipin[conn_pin]++;
00295 }
00296 else
00297 {
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 }
00310 }