VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
place_macro.c
Go to the documentation of this file.
1 /****************************************************************************************
2  Y.G.THIEN
3  29 AUG 2012
4 
5  This file contains functions related to placement macros. The term "placement macros"
6  refers to a structure that contains information on blocks that need special treatment
7  during placement and possibly routing.
8 
9  An example of placement macros is a carry chain. Blocks in a carry chain have to be
10  placed in a specific orientation or relative placement so that the carry_in's and the
11  carry_out's are properly aligned. With that, the carry chains would be able to use the
12  direct connections specified in the arch file. Direct connections with the pin's
13  fc_value 0 would be treated specially in routing where the whole carry chain would be
14  treated as a unit and regular routing would not be used to connect the carry_in's and
15  carry_out's. Floorplanning constraints may also be an example of placement macros.
16 
17  The function alloc_and_load_placement_macros allocates and loads the placement
18  macros in the following steps:
19  (1) First, go through all the block types and mark down the pins that could possibly
20  be part of a placement macros.
21  (2) Then, go through the netlist of all the pins marked in (1) to find out all the
22  heads of the placement macros using criteria depending on the type of placement
23  macros. For carry chains, the heads of the placement macros are blocks with
24  carry_in's not connected to any nets (OPEN) while the carry_out's connected to the
25  netlist with only 1 SINK.
26  (3) Traverse from the heads to the tails of the placement macros and load the
27  information in the t_pl_macro data structure. Similar to (2), tails are identified
28  with criteria depending on the type of placement macros. For carry chains, the
29  tails are blocks with carry_out's not connected to any nets (OPEN) while the
30  carry_in's is connected to the netlist which has only 1 SINK.
31 
32  The only placement macros supported at the moment are the carry chains with limited
33  functionality.
34 
35  Current support for placement macros are:
36  (1) The arch parser for direct connections is working. The specifications of the direct
37  connections are specified in sample_adder_arch.xml and also in the
38  VPR_User_Manual.doc
39  (2) The placement macros allocator and loader is working.
40  (3) The initial placement of placement macros that respects the restrictions of the
41  placement macros is working.
42  (4) The post-placement legality check for placement macros is working.
43 
44  Current limitations on placement macros are:
45  (1) One block could only be a part of a carry chain. In the future, if a block is part
46  of multiple placement macros, we should load 1 huge placement macro instead of
47  multiple placement macros that contain the same block.
48  (2) Bus direct connections (direct connections with multiple bits) are supported.
49  However, a 2-bit carry chain when loaded would become 2 1-bit carry chains.
50  And because of (1), only 1 1-bit carry chain would be loaded. In the future,
51  placement macros with multiple-bit connections or multiple 1-bit connections
52  should be allowed.
53  (3) Placement macros that span longer or wider than the chip would cause an error.
54  In the future, we *might* expand the size of the chip to accommodate such
55  placement macros that are crucial.
56 
57  In order for the carry chain support to work, two changes are required in the
58  arch file.
59  (1) For carry chain support, added in a new child in <layout> called <directlist>.
60  <directlist> specifies a list of available direct connections on the FPGA chip
61  that are necessary for direct carry chain connections. These direct connections
62  would be treated specially in routing if the fc_value for the pins is specified
63  as 0. Note that only direct connections that has fc_value 0 could be used as a
64  carry chain.
65 
66  A <directlist> may have 0 or more children called <direct>. For each <direct>,
67  there are the following fields:
68  1) name: This specifies the name given to this particular direct connection.
69  2) from_pin: This specifies the SOURCEs for this direct connection. The format
70  could be as following:
71  a) type_name.port_name, for all the pins in this port.
72  b) type_name.port_name [end_pin_index:start_pin_index], for a
73  single pin, the end_pin_index and start_pin_index could be
74  the same.
75  3) to_pin: This specifies the SINKs for this direct connection. The format is
76  the same as from_pin.
77  Note that the width of the from_pin and to_pin has to match.
78  4) x_offset: This specifies the x direction that this connection is going from
79  SOURCEs to SINKs.
80  5) y_offset: This specifies the y direction that this connection is going from
81  SOURCEs to SINKs.
82  Note that the x_offset and y_offset could not both be 0.
83  6) z_offset: This specifies the z sublocations that all the blocks in this
84  direct connection to be at.
85 
86  The example of a direct connection specification below shows a possible carry chain
87  connection going north on the FPGA chip:
88  _______________________________________________________________________________
89  | <directlist> |
90  | <direct name="adder_carry" from_pin="adder.cout" to_pin="adder.cin" |
91  | x_offset="0" y_offset="1" z_offset="0"/> |
92  | </directlist> |
93  |_______________________________________________________________________________|
94  A corresponding arch file that has this direct connection is sample_adder_arch.xml
95  A corresponding blif file that uses this direct connection is adder.blif
96 
97  (2) As mentioned in (1), carry chain connections using the directs would only be
98  recognized if the pin's fc_value is 0. In order to achieve this, pin-based fc_value
99  is required. Hence, the new <fc> tag replaces both <fc_in> and <fc_out> tags.
100 
101  A <fc> tag may have 0 or more children called <pin>. For each <fc>, there are the
102  following fields:
103  1) default_in_type: This specifies the default fc_type for input pins. They could
104  be "frac", "abs" or "full".
105  2) default_in_val: This specifies the default fc_value for input pins.
106  3) default_out_type: This specifies the default fc_type for output pins. They could
107  be "frac", "abs" or "full".
108  4) default_out_val: This specifies the default fc_value for output pins.
109 
110  As for the <pin> children, there are the following fields:
111  1) name: This specifies the name of the port/pin that the fc_type and fc_value
112  apply to. The name have to be in the format "port_name" or
113  "port_name [end_pin_index:start_pin_index]" where port_name is the name
114  of the port it apply to while end_pin_index and start_pin_index could
115  be specified to apply the fc_type and fc_value that follows to part of
116  a bus (multi-pin) port.
117  2) fc_type: This specifies the fc_type that would be applied to the specified pins.
118  3) fc_val: This specifies the fc_value that would be applied to the specified pins.
119 
120  The example of a pin-based fc_value specification below shows that the fc_values for
121  the cout and the cin ports are 0:
122  _______________________________________________________________________________
123  | <fc default_in_type="frac" default_in_val="0.15" default_out_type="frac" |
124  | default_out_val="0.15"> |
125  | <pin name="cin" fc_type="frac" fc_val="0"/> |
126  | <pin name="cout" fc_type="frac" fc_val="0"/> |
127  | </fc> |
128  |_______________________________________________________________________________|
129  A corresponding arch file that has this direct connection is sample_adder_arch.xml
130  A corresponding blif file that uses this direct connection is adder.blif
131 
132 ****************************************************************************************/
133 
134 
135 #include <stdlib.h>
136 #include <stdio.h>
137 #include <math.h>
138 #include <assert.h>
139 #include "util.h"
140 #include "vpr_types.h"
141 #include "physical_types.h"
142 #include "globals.h"
143 #include "place.h"
144 #include "read_xml_arch_file.h"
145 #include "ReadOptions.h"
146 #include "place_macro.h"
147 #include "vpr_utils.h"
148 
149 
150 /******************** File-scope variables delcarations **********************/
151 
152 /* f_idirect_from_blk_pin array allow us to quickly find pins that could be in a *
153  * direct connection. Values stored is the index of the possible direct connection *
154  * as specified in the arch file, OPEN (-1) is stored for pins that could not be *
155  * part of a direct chain conneciton. *
156  * [0...num_types-1][0...num_pins-1] */
157 static int ** f_idirect_from_blk_pin = NULL;
158 
159 /* f_direct_type_from_blk_pin array stores the value SOURCE if the pin is the *
160  * from_pin, SINK if the pin is the to_pin in the direct connection as specified in *
161  * the arch file, OPEN (-1) is stored for pins that could not be part of a direct *
162  * chain conneciton. *
163  * [0...num_types-1][0...num_pins-1] */
164 static int ** f_direct_type_from_blk_pin = NULL;
165 
166 /* f_imacro_from_blk_pin maps a blk_num to the corresponding macro index. *
167  * If the block is not part of a macro, the value OPEN (-1) is stored. *
168  * [0...num_blocks-1] */
169 static int * f_imacro_from_iblk = NULL;
170 
171 
172 /******************** Subroutine declarations ********************************/
173 
174 static void find_all_the_macro (int * num_of_macro, int * pl_macro_member_blk_num_of_this_blk,
175  int * pl_macro_idirect, int * pl_macro_num_members, int ** pl_macro_member_blk_num);
176 
177 static void free_imacro_from_iblk(void);
178 
179 static void alloc_and_load_imacro_from_iblk(t_pl_macro * macros, int num_macros);
180 
181 /******************** Subroutine definitions *********************************/
182 
183 static void find_all_the_macro (int * num_of_macro, int * pl_macro_member_blk_num_of_this_blk,
184  int * pl_macro_idirect, int * pl_macro_num_members, int ** pl_macro_member_blk_num) {
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 }
279 
280 
281 int alloc_and_load_placement_macros(t_direct_inf* directs, int num_directs, t_pl_macro ** macros){
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 }
361 
362 void get_imacro_from_iblk(int * imacro, int iblk, t_pl_macro * macros, int num_macros) {
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 }
379 
380 static void free_imacro_from_iblk(void) {
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 }
393 
394 static void alloc_and_load_imacro_from_iblk(t_pl_macro * macros, int num_macros) {
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 }
420 
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 }
void get_imacro_from_iblk(int *imacro, int iblk, t_pl_macro *macros, int num_macros)
Definition: place_macro.c:362
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
int num_blocks
Definition: place_macro.h:158
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
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
struct s_block * block
Definition: globals.c:31
void free_placement_macros_structs(void)
Definition: place_macro.c:421
struct s_net * clb_net
Definition: globals.c:28
static void free_imacro_from_iblk(void)
Definition: place_macro.c:380
int num_types
Definition: globals.c:37
Definition: slre.c:50
int * nets
Definition: vpr_types.h:562
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
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
int alloc_and_load_placement_macros(t_direct_inf *directs, int num_directs, t_pl_macro **macros)
Definition: place_macro.c:281