SRC/vpr_utils.c File Reference

#include <assert.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "vpr_utils.h"
Include dependency graph for vpr_utils.c:

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)

Function Documentation

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Generated on Tue Jan 5 15:26:54 2010 for VPR5.0 by  doxygen 1.6.1