VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
place_macro.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include "util.h"
#include "vpr_types.h"
#include "physical_types.h"
#include "globals.h"
#include "place.h"
#include "read_xml_arch_file.h"
#include "ReadOptions.h"
#include "place_macro.h"
#include "vpr_utils.h"
+ Include dependency graph for place_macro.c:

Go to the source code of this file.

Functions

static void find_all_the_macro (int *num_of_macro, int *pl_macro_member_blk_num_of_this_blk, int *pl_macro_idirect, int *pl_macro_num_members, int **pl_macro_member_blk_num)
 
static void free_imacro_from_iblk (void)
 
static void alloc_and_load_imacro_from_iblk (t_pl_macro *macros, int num_macros)
 
int alloc_and_load_placement_macros (t_direct_inf *directs, int num_directs, t_pl_macro **macros)
 
void get_imacro_from_iblk (int *imacro, int iblk, t_pl_macro *macros, int num_macros)
 
void free_placement_macros_structs (void)
 

Variables

static int ** f_idirect_from_blk_pin = NULL
 
static int ** f_direct_type_from_blk_pin = NULL
 
static int * f_imacro_from_iblk = NULL
 

Function Documentation

static void alloc_and_load_imacro_from_iblk ( t_pl_macro macros,
int  num_macros 
)
static

Definition at line 394 of file place_macro.c.

394  {
395 
396  /* Allocates and loads imacro_from_iblk array. *
397  * *
398  * The array is freed in free_placement_structs() */
399 
400  int * temp_imacro_from_iblk = NULL;
401  int imacro, imember, iblk;
402 
403  /* Allocate and initialize the values to OPEN (-1). */
404  temp_imacro_from_iblk = (int *)my_malloc(num_blocks * sizeof(int));
405  for(iblk = 0; iblk < num_blocks; iblk ++) {
406  temp_imacro_from_iblk[iblk] = OPEN;
407  }
408 
409  /* Load the values */
410  for (imacro = 0; imacro < num_macros; imacro++) {
411  for (imember = 0; imember < macros[imacro].num_blocks; imember++) {
412  iblk = macros[imacro].members[imember].blk_index;
413  temp_imacro_from_iblk[iblk] = imacro;
414  }
415  }
416 
417  /* Sets the file_scope variables to point at the arrays. */
418  f_imacro_from_iblk = temp_imacro_from_iblk;
419 }
int num_blocks
Definition: place_macro.h:158
int num_blocks
Definition: globals.c:30
t_pl_macro_member * members
Definition: place_macro.h:159
static void * my_malloc(int ibytes)
Definition: graphics.c:499
Definition: slre.c:50
static int * f_imacro_from_iblk
Definition: place_macro.c:169

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int alloc_and_load_placement_macros ( t_direct_inf directs,
int  num_directs,
t_pl_macro **  macros 
)

Definition at line 281 of file place_macro.c.

281  {
282 
283  /* This function allocates and loads the macros placement macros *
284  * and returns the total number of macros in 2 steps. *
285  * 1) Allocate temporary data structure for maximum possible *
286  * size and loops through all the blocks storing the data *
287  * relevant to the carry chains. At the same time, also count *
288  * the amount of memory required for the actual variables. *
289  * 2) Allocate the actual variables with the exact amount of *
290  * memory. Then loads the data from the temporary data *
291  * structures before freeing them. *
292  * *
293  * For pl_macro_member_blk_num, allocate for the first dimension *
294  * only at first. Allocate for the second dimemsion when I know *
295  * the size. Otherwise, the array is going to be of size *
296  * num_blocks^2 (There are big benckmarks VPR that have num_blocks *
297  * in the 100k's range). *
298  * *
299  * The placement macro array is freed by the caller(s). */
300 
301  /* Declaration of local variables */
302  int imacro, imember, num_macro;
303  int *pl_macro_idirect, *pl_macro_num_members, **pl_macro_member_blk_num,
304  *pl_macro_member_blk_num_of_this_blk;
305 
306  t_pl_macro * macro = NULL;
307 
308  /* Sets up the required variables. */
309  alloc_and_load_idirect_from_blk_pin(directs, num_directs,
311 
312  /* Allocate maximum memory for temporary variables. */
313  pl_macro_num_members = (int *) my_calloc (num_blocks , sizeof(int));
314  pl_macro_idirect = (int *) my_calloc (num_blocks , sizeof(int));
315  pl_macro_member_blk_num = (int **) my_calloc (num_blocks , sizeof(int*));
316  pl_macro_member_blk_num_of_this_blk = (int *) my_calloc (num_blocks , sizeof(int));
317 
318  /* Compute required size: *
319  * Go through all the pins with possible direct connections in *
320  * f_idirect_from_blk_pin. Count the number of heads (which is the same *
321  * as the number macros) and also the length of each macro *
322  * Head - blocks with to_pin OPEN and from_pin connected *
323  * Tail - blocks with to_pin connected and from_pin OPEN */
324  num_macro = 0;
325  find_all_the_macro (&num_macro, pl_macro_member_blk_num_of_this_blk,
326  pl_macro_idirect, pl_macro_num_members, pl_macro_member_blk_num);
327 
328  /* Allocate the memories for the macro. */
329  macro = (t_pl_macro *) my_malloc (num_macro * sizeof(t_pl_macro));
330 
331  /* Allocate the memories for the chaim members. *
332  * Load the values from the temporary data structures. */
333  for (imacro = 0; imacro < num_macro; imacro++) {
334  macro[imacro].num_blocks = pl_macro_num_members[imacro];
335  macro[imacro].members = (t_pl_macro_member *) my_malloc
336  (macro[imacro].num_blocks * sizeof(t_pl_macro_member));
337 
338  /* Load the values for each member of the macro */
339  for (imember = 0; imember < macro[imacro].num_blocks; imember++) {
340  macro[imacro].members[imember].x_offset = imember * directs[pl_macro_idirect[imacro]].x_offset;
341  macro[imacro].members[imember].y_offset = imember * directs[pl_macro_idirect[imacro]].y_offset;
342  macro[imacro].members[imember].z_offset = directs[pl_macro_idirect[imacro]].z_offset;
343  macro[imacro].members[imember].blk_index = pl_macro_member_blk_num[imacro][imember];
344  }
345  }
346 
347  /* Frees up the temporary data structures. */
348  free(pl_macro_num_members);
349  free(pl_macro_idirect);
350  for(imacro=0; imacro < num_macro; imacro++) {
351  free(pl_macro_member_blk_num[imacro]);
352  }
353  free(pl_macro_member_blk_num);
354  free(pl_macro_member_blk_num_of_this_blk);
355 
356  /* Returns the pointer to the macro by reference. */
357  *macros = macro;
358  return (num_macro);
359 
360 }
static int ** f_direct_type_from_blk_pin
Definition: place_macro.c:164
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
int num_blocks
Definition: place_macro.h:158
static int ** f_idirect_from_blk_pin
Definition: place_macro.c:157
int num_blocks
Definition: globals.c:30
static void find_all_the_macro(int *num_of_macro, int *pl_macro_member_blk_num_of_this_blk, int *pl_macro_idirect, int *pl_macro_num_members, int **pl_macro_member_blk_num)
Definition: place_macro.c:183
t_pl_macro_member * members
Definition: place_macro.h:159
static void * my_malloc(int ibytes)
Definition: graphics.c:499
void alloc_and_load_idirect_from_blk_pin(t_direct_inf *directs, int num_directs, int ***idirect_from_blk_pin, int ***direct_type_from_blk_pin)
Definition: vpr_utils.c:1073

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void find_all_the_macro ( int *  num_of_macro,
int *  pl_macro_member_blk_num_of_this_blk,
int *  pl_macro_idirect,
int *  pl_macro_num_members,
int **  pl_macro_member_blk_num 
)
static

Definition at line 183 of file place_macro.c.

184  {
185 
186  /* Compute required size: *
187  * Go through all the pins with possible direct connections in *
188  * f_idirect_from_blk_pin. Count the number of heads (which is the same *
189  * as the number macros) and also the length of each macro *
190  * Head - blocks with to_pin OPEN and from_pin connected *
191  * Tail - blocks with to_pin connected and from_pin OPEN */
192 
193  int iblk, from_iblk_pin, to_iblk_pin, from_inet, to_inet, from_idirect, to_idirect,
194  from_src_or_sink, to_src_or_sink;
195  int next_iblk, curr_iblk, next_inet, curr_inet;
196  int num_blk_pins, num_macro;
197  int imember;
198 
199  num_macro = 0;
200  for (iblk = 0; iblk < num_blocks; iblk++) {
201 
202  num_blk_pins = block[iblk].type->num_pins;
203  for (to_iblk_pin = 0; to_iblk_pin < num_blk_pins; to_iblk_pin++) {
204 
205  to_inet = block[iblk].nets[to_iblk_pin];
206  to_idirect = f_idirect_from_blk_pin[block[iblk].type->index][to_iblk_pin];
207  to_src_or_sink = f_direct_type_from_blk_pin[block[iblk].type->index][to_iblk_pin];
208 
209  // Find to_pins (SINKs) with possible direct connection but are not
210  // connected to any net (Possible head of macro)
211  if ( to_src_or_sink == SINK && to_idirect != OPEN && to_inet == OPEN ) {
212 
213  for (from_iblk_pin = 0; from_iblk_pin < num_blk_pins; from_iblk_pin++) {
214  from_inet = block[iblk].nets[from_iblk_pin];
215  from_idirect = f_idirect_from_blk_pin[block[iblk].type->index][from_iblk_pin];
216  from_src_or_sink = f_direct_type_from_blk_pin[block[iblk].type->index][from_iblk_pin];
217 
218  // Find from_pins with the same possible direct connection that are connected.
219  // Confirmed head of macro
220  if ( from_src_or_sink == SOURCE && to_idirect == from_idirect && from_inet != OPEN) {
221 
222  // Mark down that this is the first block in the macro
223  pl_macro_member_blk_num_of_this_blk[0] = iblk;
224  pl_macro_idirect[num_macro] = to_idirect;
225 
226  // Increment the num_member count.
227  pl_macro_num_members[num_macro]++;
228 
229  // Also find out how many members are in the macros,
230  // there are at least 2 members - 1 head and 1 tail.
231 
232  // Initialize the variables
233  next_inet = from_inet;
234  next_iblk = iblk;
235 
236  // Start finding the other members
237  while (next_inet != OPEN) {
238 
239  curr_iblk = next_iblk;
240  curr_inet = next_inet;
241 
242  // Assume that carry chains only has 1 sink - direct connection
243  assert(clb_net[curr_inet].num_sinks == 1);
244  next_iblk = clb_net[curr_inet].node_block[1];
245 
246  // Assume that the from_iblk_pin index is the same for the next block
247  assert (f_idirect_from_blk_pin[block[next_iblk].type->index][from_iblk_pin] == from_idirect
248  && f_direct_type_from_blk_pin[block[next_iblk].type->index][from_iblk_pin] == SOURCE);
249  next_inet = block[next_iblk].nets[from_iblk_pin];
250 
251  // Mark down this block as a member of the macro
252  imember = pl_macro_num_members[num_macro];
253  pl_macro_member_blk_num_of_this_blk[imember] = next_iblk;
254 
255  // Increment the num_member count.
256  pl_macro_num_members[num_macro]++;
257 
258  } // Found all the members of this macro at this point
259 
260  // Allocate the second dimension of the blk_num array since I now know the size
261  pl_macro_member_blk_num[num_macro] =
262  (int *) my_calloc (pl_macro_num_members[num_macro] , sizeof(int));
263  // Copy the data from the temporary array to the newly allocated array.
264  for (imember = 0; imember < pl_macro_num_members[num_macro]; imember ++)
265  pl_macro_member_blk_num[num_macro][imember] = pl_macro_member_blk_num_of_this_blk[imember];
266 
267  // Increment the macro count
268  num_macro ++;
269 
270  } // Do nothing if the from_pins does not have same possible direct connection.
271  } // Finish going through all the pins for from_pins.
272  } // Do nothing if the to_pins does not have same possible direct connection.
273  } // Finish going through all the pins for to_pins.
274  } // Finish going through all blocks.
275 
276  // Now, all the data is readily stored in the temporary data structures.
277  *num_of_macro = num_macro;
278 }
static int ** f_direct_type_from_blk_pin
Definition: place_macro.c:164
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
int * node_block
Definition: vpr_types.h:507
static int ** f_idirect_from_blk_pin
Definition: place_macro.c:157
t_type_ptr type
Definition: vpr_types.h:561
int num_blocks
Definition: globals.c:30
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
Definition: slre.c:50
int * nets
Definition: vpr_types.h:562

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void free_imacro_from_iblk ( void  )
static

Definition at line 380 of file place_macro.c.

380  {
381 
382  /* Frees the f_imacro_from_iblk array. *
383  * *
384  * This function is called when the arrays are freed in *
385  * free_placement_structs() */
386 
387  if (f_imacro_from_iblk != NULL) {
388  free(f_imacro_from_iblk);
389  f_imacro_from_iblk = NULL;
390  }
391 
392 }
static int * f_imacro_from_iblk
Definition: place_macro.c:169

+ Here is the caller graph for this function:

void free_placement_macros_structs ( void  )

Definition at line 421 of file place_macro.c.

421  {
422 
423  /* This function frees up all the static data structures used. */
424 
425  // This frees up the two arrays and set the pointers to NULL
426  int itype;
427  if ( f_idirect_from_blk_pin != NULL ) {
428  for (itype = 1; itype < num_types; itype++) {
429  free(f_idirect_from_blk_pin[itype]);
430  }
432  f_idirect_from_blk_pin = NULL;
433  }
434 
435  if ( f_direct_type_from_blk_pin != NULL ) {
436  for (itype = 1; itype < num_types; itype++) {
437  free(f_direct_type_from_blk_pin[itype]);
438  }
441  }
442 
443  // This frees up the imacro from iblk mapping array.
445 
446 }
static int ** f_direct_type_from_blk_pin
Definition: place_macro.c:164
static int ** f_idirect_from_blk_pin
Definition: place_macro.c:157
static void free_imacro_from_iblk(void)
Definition: place_macro.c:380
int num_types
Definition: globals.c:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void get_imacro_from_iblk ( int *  imacro,
int  iblk,
t_pl_macro macros,
int  num_macros 
)

Definition at line 362 of file place_macro.c.

362  {
363 
364  /* This mapping is needed for fast lookup's whether the block with index *
365  * iblk belongs to a placement macro or not. *
366  * *
367  * The array f_imacro_from_iblk is used for the mapping for speed reason *
368  * [0...num_blocks-1] */
369 
370  /* If the array is not allocated and loaded, allocate it. */
371  if (f_imacro_from_iblk == NULL) {
372  alloc_and_load_imacro_from_iblk(macros, num_macros);
373  }
374 
375  /* Return the imacro for the block. */
376  *imacro = f_imacro_from_iblk[iblk];
377 
378 }
static void alloc_and_load_imacro_from_iblk(t_pl_macro *macros, int num_macros)
Definition: place_macro.c:394
static int * f_imacro_from_iblk
Definition: place_macro.c:169

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

int** f_direct_type_from_blk_pin = NULL
static

Definition at line 164 of file place_macro.c.

int** f_idirect_from_blk_pin = NULL
static

Definition at line 157 of file place_macro.c.

int* f_imacro_from_iblk = NULL
static

Definition at line 169 of file place_macro.c.