VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
pb_type_graph.c
Go to the documentation of this file.
1 /**
2  * Jason Luu
3  * July 17, 2009
4  * pb_graph creates the internal routing edges that join together the different
5  * pb_types modes within a pb_type
6  */
7 
8 #include <stdio.h>
9 #include <assert.h>
10 #include <string.h>
11 
12 #include "util.h"
13 #include "token.h"
14 #include "arch_types.h"
15 #include "vpr_types.h"
16 #include "globals.h"
17 #include "vpr_utils.h"
18 #include "pb_type_graph.h"
21 #include "power.h"
22 
23 /* variable global to this section that indexes each pb graph pin within a cluster */
25 static struct s_linked_vptr *edges_head;
27 
28 /* TODO: Software engineering decision needed: Move this file to libarch?
29 
30  */
31 
32 static int check_pb_graph(void);
33 static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node,
34  INP t_pb_graph_node *parent_pb_graph_node, INP t_pb_type *pb_type,
35  INP int index, boolean load_power_structures);
36 
38  INOUTP t_pb_graph_node *pb_graph_parent_node,
39  INOUTP t_pb_graph_node **pb_graph_children_nodes,
40  INP const t_mode * mode, boolean load_power_structures);
41 
42 static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP int line_num,
43  INP const t_pb_graph_node *pb_graph_parent_node,
44  INP t_pb_graph_node **pb_graph_children_nodes,
45  INP boolean interconnect_error_check, INP boolean is_input_to_interc,
46  INP const t_token *tokens, INOUTP int *token_index,
47  INOUTP int *num_pins, OUTP t_pb_graph_pin ***pb_graph_pins);
48 
49 static t_pb_graph_pin * get_pb_graph_pin_from_name(INP const char * port_name,
50  INP const t_pb_graph_node * pb, INP int pin);
51 
53  INP t_interconnect * interconnect,
54  INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs,
55  INP int num_input_sets, INP int *num_input_ptrs,
56  INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs,
57  INP int num_output_sets, INP int *num_output_ptrs);
58 
60  INP t_interconnect * interconnect,
61  INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs,
62  INP int num_input_sets, INP int *num_input_ptrs,
63  INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs,
64  INP int num_output_sets, INP int *num_output_ptrs);
65 
66 static void alloc_and_load_mux_interc_edges(INP t_interconnect * interconnect,
67  INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs,
68  INP int num_input_sets, INP int *num_input_ptrs,
69  INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs,
70  INP int num_output_sets, INP int *num_output_ptrs);
71 
73 
74 static void echo_pb_rec(INP const t_pb_graph_node *pb, INP int level,
75  INP FILE * fp);
76 static void echo_pb_pins(INP t_pb_graph_pin **pb_graph_pins, INP int num_ports,
77  INP int level, INP FILE * fp);
78 static void free_pb_graph(INOUTP t_pb_graph_node *pb_graph_node);
79 
81  t_interconnect * interconnect, t_pb_graph_pin *** input_pins,
82  int num_input_sets, int * num_input_pins,
83  t_pb_graph_pin *** output_pins, int num_output_sets,
84  int * num_output_pins);
85 
86 /**
87  * Allocate memory into types and load the pb graph with interconnect edges
88  */
89 void alloc_and_load_all_pb_graphs(boolean load_power_structures) {
90  int i, errors;
91  edges_head = NULL;
92  num_edges_head = NULL;
93  for (i = 0; i < num_types; i++) {
94  if (type_descriptors[i].pb_type) {
97  sizeof(t_pb_graph_node));
98  alloc_and_load_pb_graph(type_descriptors[i].pb_graph_head, NULL,
99  type_descriptors[i].pb_type, 0, load_power_structures);
104  type_descriptors[i].pb_graph_head);
105  } else {
107  assert(&type_descriptors[i] == EMPTY_TYPE);
108  }
109  }
110 
111  errors = check_pb_graph();
112  if (errors > 0) {
113  vpr_printf(TIO_MESSAGE_ERROR, "in pb graph");
114  exit(1);
115  }
116  for (i = 0; i < num_types; i++) {
117  if (type_descriptors[i].pb_type) {
119  type_descriptors[i].pb_graph_head);
120  }
121  }
122 }
123 
124 /**
125  * Free pb graph
126  */
128  int i;
129  for (i = 0; i < num_types; i++) {
130  if (type_descriptors[i].pb_type) {
132  if (type_descriptors[i].pb_graph_head) {
133  free_pb_graph(type_descriptors[i].pb_graph_head);
134  free(type_descriptors[i].pb_graph_head);
135  }
136  }
137  }
138 }
139 
140 /**
141  * Print out the pb_type graph
142  */
143 void echo_pb_graph(char * filename) {
144  FILE *fp;
145  int i;
146 
147  fp = my_fopen(filename, "w", 0);
148 
149  fprintf(fp, "Physical Blocks Graph\n");
150  fprintf(fp, "--------------------------------------------\n\n");
151 
152  for (i = 0; i < num_types; i++) {
153  fprintf(fp, "type %s\n", type_descriptors[i].name);
154  if (type_descriptors[i].pb_graph_head)
155  echo_pb_rec(type_descriptors[i].pb_graph_head, 1, fp);
156  }
157 
158  fclose(fp);
159 }
160 
161 /**
162  * check pb_type graph and return the number of errors
163  */
164 static int check_pb_graph(void) {
165  int num_errors;
166  /* TODO: Error checks to do
167  1. All pin and edge connections are bidirectional and match each other
168  2. All pb_type names are unique in a namespace
169  3. All ports are unique in a pb_type
170  4. Number of pb of a pb_type in graph is the same as requested number
171  5. All pins are connected to edges
172  */
173  num_errors = 0;
174 
175  return num_errors;
176 }
177 
178 static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node,
179  INP t_pb_graph_node *parent_pb_graph_node, INP t_pb_type *pb_type,
180  INP int index, boolean load_power_structures) {
181  int i, j, k, i_input, i_output, i_clockport;
182 
183  pb_graph_node->placement_index = index;
184  pb_graph_node->pb_type = pb_type;
185  pb_graph_node->parent_pb_graph_node = parent_pb_graph_node;
186 
187  pb_graph_node->num_input_ports = 0;
188  pb_graph_node->num_output_ports = 0;
189  pb_graph_node->num_clock_ports = 0;
190 
191  /* Generate ports for pb graph node */
192  for (i = 0; i < pb_type->num_ports; i++) {
193  if (pb_type->ports[i].type == IN_PORT && !pb_type->ports[i].is_clock) {
194  pb_graph_node->num_input_ports++;
195  } else if (pb_type->ports[i].type == OUT_PORT) {
196  assert(!pb_type->ports[i].is_clock);
197  pb_graph_node->num_output_ports++;
198  } else {
199  assert(
200  pb_type->ports[i].is_clock && pb_type->ports[i].type == IN_PORT);
201  pb_graph_node->num_clock_ports++;
202  }
203  }
204 
205  pb_graph_node->num_input_pins = (int*) my_calloc(
206  pb_graph_node->num_input_ports, sizeof(int));
207  pb_graph_node->num_output_pins = (int*) my_calloc(
208  pb_graph_node->num_output_ports, sizeof(int));
209  pb_graph_node->num_clock_pins = (int*) my_calloc(
210  pb_graph_node->num_clock_ports, sizeof(int));
211 
212  pb_graph_node->input_pins = (t_pb_graph_pin**) my_calloc(
213  pb_graph_node->num_input_ports, sizeof(t_pb_graph_pin*));
214  pb_graph_node->output_pins = (t_pb_graph_pin**) my_calloc(
215  pb_graph_node->num_output_ports, sizeof(t_pb_graph_pin*));
216  pb_graph_node->clock_pins = (t_pb_graph_pin**) my_calloc(
217  pb_graph_node->num_clock_ports, sizeof(t_pb_graph_pin*));
218 
219  i_input = i_output = i_clockport = 0;
220  for (i = 0; i < pb_type->num_ports; i++) {
221  if (pb_type->ports[i].model_port) {
222  assert(pb_type->num_modes == 0);
223  } else {
224  assert(pb_type->num_modes != 0 || pb_type->ports[i].is_clock);
225  }
226  if (pb_type->ports[i].type == IN_PORT && !pb_type->ports[i].is_clock) {
227  pb_graph_node->input_pins[i_input] = (t_pb_graph_pin*) my_calloc(
228  pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin));
229  pb_graph_node->num_input_pins[i_input] = pb_type->ports[i].num_pins;
230  for (j = 0; j < pb_type->ports[i].num_pins; j++) {
231  pb_graph_node->input_pins[i_input][j].input_edges = NULL;
232  pb_graph_node->input_pins[i_input][j].num_input_edges = 0;
233  pb_graph_node->input_pins[i_input][j].output_edges = NULL;
234  pb_graph_node->input_pins[i_input][j].num_output_edges = 0;
235  pb_graph_node->input_pins[i_input][j].pin_number = j;
236  pb_graph_node->input_pins[i_input][j].port = &pb_type->ports[i];
237  pb_graph_node->input_pins[i_input][j].parent_node =
238  pb_graph_node;
239  pb_graph_node->input_pins[i_input][j].pin_count_in_cluster =
241  pb_graph_node->input_pins[i_input][j].type = PB_PIN_NORMAL;
242  if (pb_graph_node->pb_type->blif_model != NULL ) {
243  if (strcmp(pb_graph_node->pb_type->blif_model, ".output")
244  == 0) {
245  pb_graph_node->input_pins[i_input][j].type =
247  } else if (pb_graph_node->num_clock_ports != 0) {
248  pb_graph_node->input_pins[i_input][j].type =
250  } else {
251  pb_graph_node->input_pins[i_input][j].type =
253  }
254  }
256  }
257  i_input++;
258  } else if (pb_type->ports[i].type == OUT_PORT) {
259  pb_graph_node->output_pins[i_output] = (t_pb_graph_pin*) my_calloc(
260  pb_type->ports[i].num_pins, sizeof(t_pb_graph_pin));
261  pb_graph_node->num_output_pins[i_output] =
262  pb_type->ports[i].num_pins;
263  for (j = 0; j < pb_type->ports[i].num_pins; j++) {
264  pb_graph_node->output_pins[i_output][j].input_edges = NULL;
265  pb_graph_node->output_pins[i_output][j].num_input_edges = 0;
266  pb_graph_node->output_pins[i_output][j].output_edges = NULL;
267  pb_graph_node->output_pins[i_output][j].num_output_edges = 0;
268  pb_graph_node->output_pins[i_output][j].pin_number = j;
269  pb_graph_node->output_pins[i_output][j].port =
270  &pb_type->ports[i];
271  pb_graph_node->output_pins[i_output][j].parent_node =
272  pb_graph_node;
273  pb_graph_node->output_pins[i_output][j].pin_count_in_cluster =
275  pb_graph_node->output_pins[i_output][j].type = PB_PIN_NORMAL;
276  if (pb_graph_node->pb_type->blif_model != NULL ) {
277  if (strcmp(pb_graph_node->pb_type->blif_model, ".input")
278  == 0) {
279  pb_graph_node->output_pins[i_output][j].type =
280  PB_PIN_INPAD;
281  } else if (pb_graph_node->num_clock_ports != 0) {
282  pb_graph_node->output_pins[i_output][j].type =
284  } else {
285  pb_graph_node->output_pins[i_output][j].type =
287  }
288  }
290  }
291  i_output++;
292  } else {
293  assert(
294  pb_type->ports[i].is_clock && pb_type->ports[i].type == IN_PORT);
295  pb_graph_node->clock_pins[i_clockport] =
296  (t_pb_graph_pin*) my_calloc(pb_type->ports[i].num_pins,
297  sizeof(t_pb_graph_pin));
298  pb_graph_node->num_clock_pins[i_clockport] =
299  pb_type->ports[i].num_pins;
300  for (j = 0; j < pb_type->ports[i].num_pins; j++) {
301  pb_graph_node->clock_pins[i_clockport][j].input_edges = NULL;
302  pb_graph_node->clock_pins[i_clockport][j].num_input_edges = 0;
303  pb_graph_node->clock_pins[i_clockport][j].output_edges = NULL;
304  pb_graph_node->clock_pins[i_clockport][j].num_output_edges = 0;
305  pb_graph_node->clock_pins[i_clockport][j].pin_number = j;
306  pb_graph_node->clock_pins[i_clockport][j].port =
307  &pb_type->ports[i];
308  pb_graph_node->clock_pins[i_clockport][j].parent_node =
309  pb_graph_node;
310  pb_graph_node->clock_pins[i_clockport][j].pin_count_in_cluster =
312  pb_graph_node->clock_pins[i_clockport][j].type = PB_PIN_NORMAL;
313  if (pb_graph_node->pb_type->blif_model != NULL ) {
314  pb_graph_node->clock_pins[i_clockport][j].type =
315  PB_PIN_CLOCK;
316  }
318  }
319  i_clockport++;
320  }
321  }
322 
323  /* Power */
324  if (load_power_structures) {
325  pb_graph_node->pb_node_power = (t_pb_graph_node_power*) my_calloc(1,
326  sizeof(t_pb_graph_node_power));
327  pb_graph_node->pb_node_power->transistor_cnt_buffers = 0.;
328  pb_graph_node->pb_node_power->transistor_cnt_interc = 0.;
329  pb_graph_node->pb_node_power->transistor_cnt_pb_children = 0.;
330  }
331 
332  /* Allocate and load child nodes for each mode and create interconnect in each mode */
333  pb_graph_node->child_pb_graph_nodes = (t_pb_graph_node***) my_calloc(
334  pb_type->num_modes, sizeof(t_pb_graph_node **));
335  for (i = 0; i < pb_type->num_modes; i++) {
336  pb_graph_node->child_pb_graph_nodes[i] = (t_pb_graph_node**) my_calloc(
337  pb_type->modes[i].num_pb_type_children,
338  sizeof(t_pb_graph_node *));
339  for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
340  pb_graph_node->child_pb_graph_nodes[i][j] =
342  pb_type->modes[i].pb_type_children[j].num_pb,
343  sizeof(t_pb_graph_node));
344  for (k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) {
346  &pb_graph_node->child_pb_graph_nodes[i][j][k],
347  pb_graph_node, &pb_type->modes[i].pb_type_children[j],
348  k, load_power_structures);
349  }
350  }
351  }
352 
353  pb_graph_node->interconnect_pins = (t_interconnect_pins**) my_calloc(
354  pb_type->num_modes, sizeof(t_interconnect_pins *));
355  for (i = 0; i < pb_type->num_modes; i++) {
356  /* Create interconnect for mode */
357  alloc_and_load_mode_interconnect(pb_graph_node,
358  pb_graph_node->child_pb_graph_nodes[i], &pb_type->modes[i],
359  load_power_structures);
360  }
361 }
362 
363 static void free_pb_graph(INOUTP t_pb_graph_node *pb_graph_node) {
364  int i, j, k;
365  const t_pb_type *pb_type;
366  struct s_linked_vptr *cur, *cur_num;
367  t_pb_graph_edge *edges;
368 
369  pb_type = pb_graph_node->pb_type;
370 
371  /*free all lists of connectable input pin pointer of pb_graph_node and it's children*/
372  /*free_list_of_connectable_input_pin_ptrs (pb_graph_node);*/
373 
374  /* Free ports for pb graph node */
375  for (i = 0; i < pb_graph_node->num_input_ports; i++) {
376  for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
377  if (pb_graph_node->input_pins[i][j].pin_timing)
378  free(pb_graph_node->input_pins[i][j].pin_timing);
379  if (pb_graph_node->input_pins[i][j].pin_timing_del_max)
380  free(pb_graph_node->input_pins[i][j].pin_timing_del_max);
381  if (pb_graph_node->input_pins[i][j].input_edges)
382  free(pb_graph_node->input_pins[i][j].input_edges);
383  if (pb_graph_node->input_pins[i][j].output_edges)
384  free(pb_graph_node->input_pins[i][j].output_edges);
385  if (pb_graph_node->input_pins[i][j].parent_pin_class)
386  free(pb_graph_node->input_pins[i][j].parent_pin_class);
387  }
388  free(pb_graph_node->input_pins[i]);
389  }
390  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
391  for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
392  if (pb_graph_node->output_pins[i][j].pin_timing)
393  free(pb_graph_node->output_pins[i][j].pin_timing);
394  if (pb_graph_node->output_pins[i][j].pin_timing_del_max)
395  free(pb_graph_node->output_pins[i][j].pin_timing_del_max);
396  if (pb_graph_node->output_pins[i][j].input_edges)
397  free(pb_graph_node->output_pins[i][j].input_edges);
398  if (pb_graph_node->output_pins[i][j].output_edges)
399  free(pb_graph_node->output_pins[i][j].output_edges);
400  if (pb_graph_node->output_pins[i][j].parent_pin_class)
401  free(pb_graph_node->output_pins[i][j].parent_pin_class);
402 
403  if (pb_graph_node->output_pins[i][j].list_of_connectable_input_pin_ptrs) {
404  for (k = 0; k < pb_graph_node->pb_type->depth; k++) {
405  if (pb_graph_node->output_pins[i][j].list_of_connectable_input_pin_ptrs[k]) {
406  free(
407  pb_graph_node->output_pins[i][j].list_of_connectable_input_pin_ptrs[k]);
408  }
409  }
410  free(
411  pb_graph_node->output_pins[i][j].list_of_connectable_input_pin_ptrs);
412  }
413 
414  if (pb_graph_node->output_pins[i][j].num_connectable_primtive_input_pins)
415  free(
416  pb_graph_node->output_pins[i][j].num_connectable_primtive_input_pins);
417  }
418  free(pb_graph_node->output_pins[i]);
419  }
420  for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
421  for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
422  if (pb_graph_node->clock_pins[i][j].pin_timing)
423  free(pb_graph_node->clock_pins[i][j].pin_timing);
424  if (pb_graph_node->clock_pins[i][j].pin_timing_del_max)
425  free(pb_graph_node->clock_pins[i][j].pin_timing_del_max);
426  if (pb_graph_node->clock_pins[i][j].input_edges)
427  free(pb_graph_node->clock_pins[i][j].input_edges);
428  if (pb_graph_node->clock_pins[i][j].output_edges)
429  free(pb_graph_node->clock_pins[i][j].output_edges);
430  if (pb_graph_node->clock_pins[i][j].parent_pin_class)
431  free(pb_graph_node->clock_pins[i][j].parent_pin_class);
432  }
433  free(pb_graph_node->clock_pins[i]);
434  }
435 
436 
437  for(i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
438  free(pb_graph_node->interconnect_pins[i]);
439  }
440  free(pb_graph_node->interconnect_pins);
441 
442  free(pb_graph_node->input_pins);
443  free(pb_graph_node->output_pins);
444  free(pb_graph_node->clock_pins);
445 
446  free(pb_graph_node->num_input_pins);
447  free(pb_graph_node->num_output_pins);
448  free(pb_graph_node->num_clock_pins);
449 
450  free(pb_graph_node->input_pin_class_size);
451  free(pb_graph_node->output_pin_class_size);
452 
453  for (i = 0; i < pb_type->num_modes; i++) {
454  for (j = 0; j < pb_type->modes[i].num_pb_type_children; j++) {
455  for (k = 0; k < pb_type->modes[i].pb_type_children[j].num_pb; k++) {
456  free_pb_graph(&pb_graph_node->child_pb_graph_nodes[i][j][k]);
457  }
458  free(pb_graph_node->child_pb_graph_nodes[i][j]);
459  }
460  free(pb_graph_node->child_pb_graph_nodes[i]);
461  }
462  free(pb_graph_node->child_pb_graph_nodes);
463 
464  while (edges_head != NULL ) {
465  cur = edges_head;
466  cur_num = num_edges_head;
467  edges = (t_pb_graph_edge*) cur->data_vptr;
468  for (i = 0; i < (long) cur_num->data_vptr; i++) {
469  free(edges[i].input_pins);
470  free(edges[i].output_pins);
471  if (edges[i].pack_pattern_indices) {
472  free(edges[i].pack_pattern_indices);
473  }
474  if (edges[i].pack_pattern_names) {
475  free(edges[i].pack_pattern_names);
476  }
477  }
478  edges_head = edges_head->next;
479  num_edges_head = num_edges_head->next;
480  free(edges);
481  free(cur_num);
482  free(cur);
483  }
484 }
485 
487  t_interconnect * interconnect, t_pb_graph_pin *** input_pins,
488  int num_input_sets, int * num_input_pins,
489  t_pb_graph_pin *** output_pins, int num_output_sets,
490  int * num_output_pins) {
491  int set_idx;
492  int pin_idx;
493  int port_idx;
494  int num_ports;
495 
496  interc_pins->interconnect = interconnect;
497 
498  switch (interconnect->type) {
499  case DIRECT_INTERC:
500  assert(num_output_sets == 1);
501  /* Fall through here */
502 
503  case MUX_INTERC:
504  if (!interconnect->interconnect_power->port_info_initialized) {
505  for (set_idx = 0; set_idx < num_input_sets; set_idx++) {
506  assert(num_input_pins[set_idx] == num_output_pins[0]);
507  }
508  interconnect->interconnect_power->num_pins_per_port =
509  num_input_pins[0];
510  interconnect->interconnect_power->num_input_ports = num_input_sets;
511  interconnect->interconnect_power->num_output_ports = 1;
512 
513  /* No longer used - mux architectures are not configurable, the
514  * default is always assumed
515  if (interconnect->mux_arch) {
516  interconnect->mux_arch->num_inputs =
517  interconnect->num_input_ports;
518 
519  mux_arch_fix_levels(interconnect->mux_arch);
520 
521  interconnect->mux_arch->mux_graph_head =
522  alloc_and_load_mux_graph(interconnect->num_input_ports,
523  interconnect->mux_arch->levels);
524  }
525  */
526 
528  }
529 
530  interc_pins->input_pins = (t_pb_graph_pin***) my_calloc(num_input_sets,
531  sizeof(t_pb_graph_pin**));
532  for (set_idx = 0; set_idx < num_input_sets; set_idx++) {
533  interc_pins->input_pins[set_idx] = (t_pb_graph_pin**) my_calloc(
534  interconnect->interconnect_power->num_pins_per_port,
535  sizeof(t_pb_graph_pin*));
536  }
537 
538  interc_pins->output_pins = (t_pb_graph_pin***) my_calloc(1,
539  sizeof(t_pb_graph_pin**));
540  interc_pins->output_pins[0] = (t_pb_graph_pin**) my_calloc(
541  interconnect->interconnect_power->num_pins_per_port,
542  sizeof(t_pb_graph_pin*));
543 
544  for (pin_idx = 0;
545  pin_idx < interconnect->interconnect_power->num_pins_per_port;
546  pin_idx++) {
547  for (set_idx = 0; set_idx < num_input_sets; set_idx++) {
548  interc_pins->input_pins[set_idx][pin_idx] =
549  input_pins[set_idx][pin_idx];
550  }
551  interc_pins->output_pins[0][pin_idx] = output_pins[0][pin_idx];
552  }
553 
554  break;
555  case COMPLETE_INTERC:
556 
557  if (!interconnect->interconnect_power->port_info_initialized) {
558  /* The code does not support bus-based crossbars, so all pins from all input sets
559  * connect to all pins from all output sets */
560  interconnect->interconnect_power->num_pins_per_port = 1;
561 
562  num_ports = 0;
563  for (set_idx = 0; set_idx < num_input_sets; set_idx++) {
564  num_ports += num_input_pins[set_idx];
565  }
566  interconnect->interconnect_power->num_input_ports = num_ports;
567 
568  num_ports = 0;
569  for (set_idx = 0; set_idx < num_output_sets; set_idx++) {
570  num_ports += num_output_pins[set_idx];
571  }
572  interconnect->interconnect_power->num_output_ports = num_ports;
573 
574  /*
575  if (interconnect->mux_arch) {
576  interconnect->mux_arch->num_inputs =
577  interconnect->num_input_ports;
578 
579  mux_arch_fix_levels(interconnect->mux_arch);
580 
581  interconnect->mux_arch->mux_graph_head =
582  alloc_and_load_mux_graph(interconnect->num_input_ports,
583  interconnect->mux_arch->levels);
584  }*/
585 
587  }
588 
589  /* Input Pins */
590  interc_pins->input_pins = (t_pb_graph_pin ***) my_calloc(
591  interconnect->interconnect_power->num_input_ports,
592  sizeof(t_pb_graph_pin**));
593  for (port_idx = 0;
594  port_idx < interconnect->interconnect_power->num_input_ports;
595  port_idx++) {
596  interc_pins->input_pins[port_idx] = (t_pb_graph_pin**) my_calloc(
597  interconnect->interconnect_power->num_pins_per_port,
598  sizeof(t_pb_graph_pin*));
599  }
600  num_ports = 0;
601  for (set_idx = 0; set_idx < num_input_sets; set_idx++) {
602  for (pin_idx = 0; pin_idx < num_input_pins[set_idx]; pin_idx++) {
603  interc_pins->input_pins[num_ports++][0] =
604  input_pins[set_idx][pin_idx];
605  }
606  }
607 
608  /* Output Pins */
609  interc_pins->output_pins = (t_pb_graph_pin ***) my_calloc(
610  interconnect->interconnect_power->num_output_ports,
611  sizeof(t_pb_graph_pin**));
612  for (port_idx = 0;
613  port_idx < interconnect->interconnect_power->num_output_ports;
614  port_idx++) {
615  interc_pins->output_pins[port_idx] = (t_pb_graph_pin **) my_calloc(
616  interconnect->interconnect_power->num_pins_per_port,
617  sizeof(t_pb_graph_pin*));
618  }
619  num_ports = 0;
620  for (set_idx = 0; set_idx < num_output_sets; set_idx++) {
621  for (pin_idx = 0; pin_idx < num_output_pins[set_idx]; pin_idx++) {
622  interc_pins->output_pins[num_ports++][0] =
623  output_pins[set_idx][pin_idx];
624  }
625  }
626 
627  break;
628  }
629 
630 }
631 
632 /**
633  * Generate interconnect associated with a mode of operation
634  * pb_graph_parent_node: parent node of pb in mode
635  * pb_graph_children_nodes: [0..num_pb_type_in_mode-1][0..num_pb]
636  * mode: mode of operation
637  */
639  INOUTP t_pb_graph_node *pb_graph_parent_node,
640  INOUTP t_pb_graph_node **pb_graph_children_nodes,
641  INP const t_mode * mode, boolean load_power_structures) {
642  int i, j;
643  int *num_input_pb_graph_node_pins, *num_output_pb_graph_node_pins; /* number of pins in a set [0..num_sets-1] */
644  int num_input_pb_graph_node_sets, num_output_pb_graph_node_sets;
645  t_pb_graph_pin *** input_pb_graph_node_pins, ***output_pb_graph_node_pins;
646 
647  if (load_power_structures) {
648  assert(pb_graph_parent_node->interconnect_pins[mode->index] == NULL);
649  pb_graph_parent_node->interconnect_pins[mode->index] =
650  (t_interconnect_pins*) my_calloc(mode->num_interconnect,
651  sizeof(t_interconnect_pins));
652  }
653 
654  for (i = 0; i < mode->num_interconnect; i++) {
655  /* determine the interconnect input and output pins */
656  input_pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(
657  mode->interconnect[i].line_num, pb_graph_parent_node,
658  pb_graph_children_nodes, mode->interconnect[i].input_string,
659  &num_input_pb_graph_node_pins, &num_input_pb_graph_node_sets,
660  TRUE, TRUE);
661 
662  output_pb_graph_node_pins = alloc_and_load_port_pin_ptrs_from_string(
663  mode->interconnect[i].line_num, pb_graph_parent_node,
664  pb_graph_children_nodes, mode->interconnect[i].output_string,
665  &num_output_pb_graph_node_pins, &num_output_pb_graph_node_sets,
666  FALSE, TRUE);
667 
668  if (load_power_structures) {
670  &pb_graph_parent_node->interconnect_pins[mode->index][i],
671  &mode->interconnect[i], input_pb_graph_node_pins,
672  num_input_pb_graph_node_sets, num_input_pb_graph_node_pins,
673  output_pb_graph_node_pins, num_output_pb_graph_node_sets,
674  num_output_pb_graph_node_pins);
675  }
676 
677  /* process the interconnect based on its type */
678  switch (mode->interconnect[i].type) {
679 
680  case COMPLETE_INTERC:
681  alloc_and_load_complete_interc_edges(&mode->interconnect[i],
682  input_pb_graph_node_pins, num_input_pb_graph_node_sets,
683  num_input_pb_graph_node_pins, output_pb_graph_node_pins,
684  num_output_pb_graph_node_sets,
685  num_output_pb_graph_node_pins);
686 
687  break;
688 
689  case DIRECT_INTERC:
690  alloc_and_load_direct_interc_edges(&mode->interconnect[i],
691  input_pb_graph_node_pins, num_input_pb_graph_node_sets,
692  num_input_pb_graph_node_pins, output_pb_graph_node_pins,
693  num_output_pb_graph_node_sets,
694  num_output_pb_graph_node_pins);
695  break;
696 
697  case MUX_INTERC:
698  alloc_and_load_mux_interc_edges(&mode->interconnect[i],
699  input_pb_graph_node_pins, num_input_pb_graph_node_sets,
700  num_input_pb_graph_node_pins, output_pb_graph_node_pins,
701  num_output_pb_graph_node_sets,
702  num_output_pb_graph_node_pins);
703 
704  break;
705 
706  default:
707  vpr_printf(TIO_MESSAGE_ERROR,
708  "[LINE %d] Unknown interconnect %d for mode %s in pb_type %s, input %s, output %s\n",
709  mode->interconnect[i].line_num, mode->interconnect[i].type,
710  mode->name, pb_graph_parent_node->pb_type->name,
711  mode->interconnect[i].input_string,
712  mode->interconnect[i].output_string);
713  exit(1);
714  }
715  for (j = 0; j < num_input_pb_graph_node_sets; j++) {
716  free(input_pb_graph_node_pins[j]);
717  }
718  free(input_pb_graph_node_pins);
719  for (j = 0; j < num_output_pb_graph_node_sets; j++) {
720  free(output_pb_graph_node_pins[j]);
721  }
722  free(output_pb_graph_node_pins);
723  free(num_input_pb_graph_node_pins);
724  free(num_output_pb_graph_node_pins);
725  }
726 }
727 
728 /**
729  * creates an array of pointers to the pb graph node pins in order from the port string
730  * returns t_pb_graph_pin ptr indexed by [0..num_sets_in_port - 1][0..num_ptrs - 1]
731  */
733  INP const t_pb_graph_node *pb_graph_parent_node,
734  INP t_pb_graph_node **pb_graph_children_nodes,
735  INP const char * port_string, OUTP int ** num_ptrs, OUTP int * num_sets,
736  INP boolean is_input_to_interc, INP boolean interconnect_error_check) {
737  t_token * tokens;
738  int num_tokens, curr_set;
739  int i;
740  boolean in_squig_bracket, success;
741 
742  t_pb_graph_pin ***pb_graph_pins;
743 
744  num_tokens = 0;
745  tokens = GetTokensFromString(port_string, &num_tokens);
746  *num_sets = 0;
747  in_squig_bracket = FALSE;
748 
749  /* count the number of sets available */
750  for (i = 0; i < num_tokens; i++) {
751  assert(tokens[i].type != TOKEN_NULL);
752  if (tokens[i].type == TOKEN_OPEN_SQUIG_BRACKET) {
753  if (in_squig_bracket) {
754  vpr_printf(TIO_MESSAGE_ERROR,
755  "[LINE %d] { inside { in port %s\n", line_num,
756  port_string);
757  exit(1);
758  }
759  in_squig_bracket = TRUE;
760  } else if (tokens[i].type == TOKEN_CLOSE_SQUIG_BRACKET) {
761  if (!in_squig_bracket) {
762  (*num_sets)++;
763  vpr_printf(TIO_MESSAGE_ERROR,
764  "[LINE %d] No matching '{' for '}' in port %s\n",
765  line_num, port_string);
766  exit(1);
767  }
768  in_squig_bracket = FALSE;
769  } else if (tokens[i].type == TOKEN_DOT) {
770  if (!in_squig_bracket) {
771  (*num_sets)++;
772  }
773  }
774  }
775 
776  if (in_squig_bracket) {
777  (*num_sets)++;
778  vpr_printf(TIO_MESSAGE_ERROR,
779  "[LINE %d] No matching '{' for '}' in port %s\n", line_num,
780  port_string);
781  exit(1);
782  }
783 
784  pb_graph_pins = (t_pb_graph_pin***) my_calloc(*num_sets,
785  sizeof(t_pb_graph_pin**));
786  *num_ptrs = (int*) my_calloc(*num_sets, sizeof(int));
787 
788  curr_set = 0;
789  for (i = 0; i < num_tokens; i++) {
790  assert(tokens[i].type != TOKEN_NULL);
791  if (tokens[i].type == TOKEN_OPEN_SQUIG_BRACKET) {
792  if (in_squig_bracket) {
793  vpr_printf(TIO_MESSAGE_ERROR,
794  "[LINE %d] { inside { in port %s\n", line_num,
795  port_string);
796  exit(1);
797  }
798  in_squig_bracket = TRUE;
799  } else if (tokens[i].type == TOKEN_CLOSE_SQUIG_BRACKET) {
800  if ((*num_ptrs)[curr_set] == 0) {
801  vpr_printf(TIO_MESSAGE_ERROR,
802  "[LINE %d] No data contained in {} in port %s\n",
803  line_num, port_string);
804  exit(1);
805  }
806  if (!in_squig_bracket) {
807  curr_set++;
808  vpr_printf(TIO_MESSAGE_ERROR,
809  "[LINE %d] No matching '{' for '}' in port %s\n",
810  line_num, port_string);
811  exit(1);
812  }
813  in_squig_bracket = FALSE;
814  } else if (tokens[i].type == TOKEN_STRING) {
815 
817  pb_graph_parent_node, pb_graph_children_nodes,
818  interconnect_error_check, is_input_to_interc, tokens, &i,
819  &((*num_ptrs)[curr_set]), &pb_graph_pins[curr_set]);
820 
821  if (!success) {
822  vpr_printf(TIO_MESSAGE_ERROR,
823  "[LINE %d] syntax error processing port string %s\n",
824  line_num, port_string);
825  exit(1);
826  }
827 
828  if (!in_squig_bracket) {
829  curr_set++;
830  }
831  }
832  }
833  assert(curr_set == *num_sets);
834  freeTokens(tokens, num_tokens);
835  return pb_graph_pins;
836 }
837 
838 /**
839  * Creates edges to connect all input pins to output pins
840  */
842  INP t_interconnect *interconnect,
843  INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs,
844  INP int num_input_sets, INP int *num_input_ptrs,
845  INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs,
846  INP int num_output_sets, INP int *num_output_ptrs) {
847  int i_inset, i_outset, i_inpin, i_outpin;
848  int in_count, out_count;
849  t_pb_graph_edge *edges;
850  int i_edge;
851  struct s_linked_vptr *cur;
852 
853  assert(interconnect->infer_annotations == FALSE);
854 
855  /* Allocate memory for edges, and reallocate more memory for pins connecting to those edges */
856  in_count = out_count = 0;
857 
858  for (i_inset = 0; i_inset < num_input_sets; i_inset++) {
859  in_count += num_input_ptrs[i_inset];
860  }
861  for (i_outset = 0; i_outset < num_output_sets; i_outset++) {
862  out_count += num_output_ptrs[i_outset];
863  }
864 
865  edges = (t_pb_graph_edge*) my_calloc(in_count * out_count,
866  sizeof(t_pb_graph_edge));
867  cur = (struct s_linked_vptr*) my_malloc(sizeof(struct s_linked_vptr));
868  cur->next = edges_head;
869  edges_head = cur;
870  cur->data_vptr = (void *) edges;
871  cur = (struct s_linked_vptr*) my_malloc(sizeof(struct s_linked_vptr));
872  cur->next = num_edges_head;
873  num_edges_head = cur;
874  cur->data_vptr = (void *) ((long) in_count * out_count);
875 
876  for (i_inset = 0; i_inset < num_input_sets; i_inset++) {
877  for (i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
878  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges =
880  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges,
881  (input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges
882  + out_count) * sizeof(t_pb_graph_edge *));
883  }
884  }
885 
886  for (i_outset = 0; i_outset < num_output_sets; i_outset++) {
887  for (i_outpin = 0; i_outpin < num_output_ptrs[i_outset]; i_outpin++) {
888  output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges =
890  output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges,
891  (output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges
892  + in_count) * sizeof(t_pb_graph_edge *));
893  }
894  }
895 
896  i_edge = 0;
897 
898  /* Load connections between pins and record these updates in the edges */
899  for (i_inset = 0; i_inset < num_input_sets; i_inset++) {
900  for (i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
901  for (i_outset = 0; i_outset < num_output_sets; i_outset++) {
902  for (i_outpin = 0; i_outpin < num_output_ptrs[i_outset];
903  i_outpin++) {
904 
905  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges[input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges] =
906  &edges[i_edge];
907  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges++;
908  output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->input_edges[output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges] =
909  &edges[i_edge];
910  output_pb_graph_node_pin_ptrs[i_outset][i_outpin]->num_input_edges++;
911 
912  edges[i_edge].num_input_pins = 1;
913  edges[i_edge].input_pins = (t_pb_graph_pin **) my_malloc(
914  sizeof(t_pb_graph_pin *));
915  edges[i_edge].input_pins[0] =
916  input_pb_graph_node_pin_ptrs[i_inset][i_inpin];
917  edges[i_edge].num_output_pins = 1;
918  edges[i_edge].output_pins = (t_pb_graph_pin **) my_malloc(
919  sizeof(t_pb_graph_pin *));
920  edges[i_edge].output_pins[0] =
921  output_pb_graph_node_pin_ptrs[i_outset][i_outpin];
922 
923  edges[i_edge].interconnect = interconnect;
924  edges[i_edge].driver_set = i_inset;
925  edges[i_edge].driver_pin = i_inpin;
926 
927  i_edge++;
928  }
929  }
930  }
931  }
932  assert(i_edge == in_count * out_count);
933 }
934 
936  INP t_interconnect *interconnect,
937  INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs,
938  INP int num_input_sets, INP int *num_input_ptrs,
939  INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs,
940  INP int num_output_sets, INP int *num_output_ptrs) {
941 
942  int i;
943  t_pb_graph_edge *edges;
944  struct s_linked_vptr *cur;
945 
946  /* Allocate memory for edges */
947  if (!(num_input_sets == 1 && num_output_sets == 1)) {
948  vpr_printf(TIO_MESSAGE_ERROR,
949  "[LINE %d] Direct interconnect allows connections from one set of pins to one other set\n",
950  interconnect->line_num);
951  exit(1);
952  }
953  if (!(num_input_ptrs[0] == num_output_ptrs[0])) {
954  vpr_printf(TIO_MESSAGE_ERROR,
955  "[LINE %d] Direct interconnect must use an equal number of pins\n",
956  interconnect->line_num);
957  exit(1);
958  }
959 
960  edges = (t_pb_graph_edge*) my_calloc(num_input_ptrs[0],
961  sizeof(t_pb_graph_edge));
962  cur = (struct s_linked_vptr*) my_malloc(sizeof(struct s_linked_vptr));
963  cur->next = edges_head;
964  edges_head = cur;
965  cur->data_vptr = (void *) edges;
966  cur = (struct s_linked_vptr*) my_malloc(sizeof(struct s_linked_vptr));
967  cur->next = num_edges_head;
968  num_edges_head = cur;
969  cur->data_vptr = (void *) ((long) num_input_ptrs[0]);
970 
971  /* Reallocate memory for pins and load connections between pins and record these updates in the edges */
972  for (i = 0; i < num_input_ptrs[0]; i++) {
973  input_pb_graph_node_pin_ptrs[0][i]->output_edges =
975  input_pb_graph_node_pin_ptrs[0][i]->output_edges,
976  (input_pb_graph_node_pin_ptrs[0][i]->num_output_edges
977  + 1) * sizeof(t_pb_graph_edge *));
978  input_pb_graph_node_pin_ptrs[0][i]->output_edges[input_pb_graph_node_pin_ptrs[0][i]->num_output_edges] =
979  &edges[i];
980  input_pb_graph_node_pin_ptrs[0][i]->num_output_edges++;
981 
982  output_pb_graph_node_pin_ptrs[0][i]->input_edges =
984  output_pb_graph_node_pin_ptrs[0][i]->input_edges,
985  (output_pb_graph_node_pin_ptrs[0][i]->num_input_edges
986  + 1) * sizeof(t_pb_graph_edge *));
987  output_pb_graph_node_pin_ptrs[0][i]->input_edges[output_pb_graph_node_pin_ptrs[0][i]->num_input_edges] =
988  &edges[i];
989  output_pb_graph_node_pin_ptrs[0][i]->num_input_edges++;
990 
991  edges[i].num_input_pins = 1;
992  edges[i].input_pins = (t_pb_graph_pin **) my_malloc(
993  sizeof(t_pb_graph_pin *));
994  edges[i].input_pins[0] = input_pb_graph_node_pin_ptrs[0][i];
995  edges[i].num_output_pins = 1;
996  edges[i].output_pins = (t_pb_graph_pin **) my_malloc(
997  sizeof(t_pb_graph_pin *));
998  edges[i].output_pins[0] = output_pb_graph_node_pin_ptrs[0][i];
999 
1000  edges[i].interconnect = interconnect;
1001  edges[i].driver_set = 0;
1002  edges[i].driver_pin = i;
1003  edges[i].infer_pattern = interconnect->infer_annotations;
1004  }
1005 }
1006 
1008  INOUTP t_pb_graph_pin *** input_pb_graph_node_pin_ptrs,
1009  INP int num_input_sets, INP int *num_input_ptrs,
1010  INOUTP t_pb_graph_pin *** output_pb_graph_node_pin_ptrs,
1011  INP int num_output_sets, INP int *num_output_ptrs) {
1012  int i_inset, i_inpin, i_outpin;
1013  t_pb_graph_edge *edges;
1014  struct s_linked_vptr *cur;
1015 
1016  assert(interconnect->infer_annotations == FALSE);
1017 
1018  /* Allocate memory for edges, and reallocate more memory for pins connecting to those edges */
1019  if (num_output_sets != 1) {
1020  vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Mux must have one output\n",
1021  interconnect->line_num);
1022  exit(1);
1023  }
1024 
1025  edges = (t_pb_graph_edge*) my_calloc(num_input_sets,
1026  sizeof(t_pb_graph_edge));
1027  cur = (struct s_linked_vptr*) my_malloc(sizeof(struct s_linked_vptr));
1028  cur->next = edges_head;
1029  edges_head = cur;
1030  cur->data_vptr = (void *) edges;
1031  cur = (struct s_linked_vptr*) my_malloc(sizeof(struct s_linked_vptr));
1032  cur->next = num_edges_head;
1033  num_edges_head = cur;
1034  cur->data_vptr = (void *) ((long) num_input_sets);
1035 
1036  for (i_inset = 0; i_inset < num_input_sets; i_inset++) {
1037  for (i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
1038  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges =
1040  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges,
1041  (input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges
1042  + 1) * sizeof(t_pb_graph_edge *));
1043  }
1044  }
1045 
1046  for (i_outpin = 0; i_outpin < num_output_ptrs[0]; i_outpin++) {
1047  output_pb_graph_node_pin_ptrs[0][i_outpin]->input_edges =
1049  output_pb_graph_node_pin_ptrs[0][i_outpin]->input_edges,
1050  (output_pb_graph_node_pin_ptrs[0][i_outpin]->num_input_edges
1051  + num_input_sets) * sizeof(t_pb_graph_edge *));
1052  }
1053 
1054  /* Load connections between pins and record these updates in the edges */
1055  for (i_inset = 0; i_inset < num_input_sets; i_inset++) {
1056  if (num_output_ptrs[0] != num_input_ptrs[i_inset]) {
1057  vpr_printf(TIO_MESSAGE_ERROR,
1058  "[LINE %d] # of pins for a particular data line of a mux must equal number of pins at output of mux\n",
1059  interconnect->line_num);
1060  exit(1);
1061  }
1062  edges[i_inset].input_pins = (t_pb_graph_pin**) my_calloc(
1063  num_output_ptrs[0], sizeof(t_pb_graph_pin *));
1064  edges[i_inset].output_pins = (t_pb_graph_pin**) my_calloc(
1065  num_output_ptrs[0], sizeof(t_pb_graph_pin *));
1066  edges[i_inset].num_input_pins = num_output_ptrs[0];
1067  edges[i_inset].num_output_pins = num_output_ptrs[0];
1068  for (i_inpin = 0; i_inpin < num_input_ptrs[i_inset]; i_inpin++) {
1069  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->output_edges[input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges] =
1070  &edges[i_inset];
1071  input_pb_graph_node_pin_ptrs[i_inset][i_inpin]->num_output_edges++;
1072  output_pb_graph_node_pin_ptrs[0][i_inpin]->input_edges[output_pb_graph_node_pin_ptrs[0][i_inpin]->num_input_edges] =
1073  &edges[i_inset];
1074  output_pb_graph_node_pin_ptrs[0][i_inpin]->num_input_edges++;
1075 
1076  edges[i_inset].input_pins[i_inpin] =
1077  input_pb_graph_node_pin_ptrs[i_inset][i_inpin];
1078  edges[i_inset].output_pins[i_inpin] =
1079  output_pb_graph_node_pin_ptrs[0][i_inpin];
1080 
1081  if (i_inpin != 0) {
1082  vpr_printf(TIO_MESSAGE_ERROR,
1083  "[LINE %d] Bus-based mux not yet supported, will consider for future work\n",
1084  interconnect->line_num);
1085  exit(1);
1086  }
1087  edges[i_inset].interconnect = interconnect;
1088  edges[i_inset].driver_set = i_inset;
1089  edges[i_inset].driver_pin = i_inpin;
1090  }
1091  }
1092 }
1093 
1094 /**
1095  * populate array of pb graph pins for a single variable of type pb_type[int:int].port[int:int]
1096  * pb_graph_pins: pointer to array from [0..num_port_pins] of pb_graph_pin pointers
1097  * tokens: array of tokens to scan
1098  * num_pins: current number of pins in pb_graph_pin array
1099  */
1101  INP const t_pb_graph_node *pb_graph_parent_node,
1102  INP t_pb_graph_node **pb_graph_children_nodes,
1103  INP boolean interconnect_error_check, INP boolean is_input_to_interc,
1104  INP const t_token *tokens, INOUTP int *token_index,
1105  INOUTP int *num_pins, OUTP t_pb_graph_pin ***pb_graph_pins) {
1106 
1107  int i, j, ipin, ipb;
1108  int pb_msb, pb_lsb;
1109  int pin_msb, pin_lsb;
1110  int max_pb_node_array;
1111  const t_pb_graph_node *pb_node_array;
1112  char *port_name;
1113  t_port *iport;
1114  int add_or_subtract_pb, add_or_subtract_pin;
1115  boolean found;
1116  t_mode *mode = NULL;
1117 
1118  assert(tokens[*token_index].type == TOKEN_STRING);
1119  pb_node_array = NULL;
1120  max_pb_node_array = 0;
1121 
1122  if (pb_graph_children_nodes)
1123  mode = pb_graph_children_nodes[0][0].pb_type->parent_mode;
1124 
1125  pb_msb = pb_lsb = OPEN;
1126  pin_msb = pin_lsb = OPEN;
1127 
1128  /* parse pb */
1129  found = FALSE;
1130  if (0
1131  == strcmp(pb_graph_parent_node->pb_type->name,
1132  tokens[*token_index].data)) {
1133  pb_node_array = pb_graph_parent_node;
1134  max_pb_node_array = 1;
1135  pb_msb = pb_lsb = 0;
1136  found = TRUE;
1137  (*token_index)++;
1138  if (tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) {
1139  (*token_index)++;
1140  if (!checkTokenType(tokens[*token_index], TOKEN_INT)) {
1141  return FALSE;
1142  }
1143  pb_msb = my_atoi(tokens[*token_index].data);
1144  (*token_index)++;
1145  if (!checkTokenType(tokens[*token_index], TOKEN_COLON)) {
1146  if (!checkTokenType(tokens[*token_index],
1148  return FALSE;
1149  }
1150  pb_lsb = pb_msb;
1151  (*token_index)++;
1152  } else {
1153  (*token_index)++;
1154  if (!checkTokenType(tokens[*token_index], TOKEN_INT)) {
1155  return FALSE;
1156  }
1157  pb_lsb = my_atoi(tokens[*token_index].data);
1158  (*token_index)++;
1159  if (!checkTokenType(tokens[*token_index],
1161  return FALSE;
1162  }
1163  (*token_index)++;
1164  }
1165  /* Check to make sure indices from user match internal data structures for the indices of the parent */
1166  if ((pb_lsb != pb_msb)
1167  && (pb_lsb != pb_graph_parent_node->placement_index)) {
1168  vpr_printf(TIO_MESSAGE_ERROR,
1169  "[LINE %d] Incorrect placement index for %s, expected index %d\n",
1170  line_num, tokens[0].data,
1171  pb_graph_parent_node->placement_index);
1172  return FALSE;
1173  }
1174  pb_lsb = pb_msb = 0; /* Internal representation of parent is always 0 */
1175  }
1176  } else {
1177  if (mode == NULL ) {
1178  vpr_printf(TIO_MESSAGE_ERROR,
1179  "[LINE %d] pb_graph_parent_node %s failed\n", line_num,
1180  pb_graph_parent_node->pb_type->name);
1181  exit(1);
1182  }
1183  for (i = 0; i < mode->num_pb_type_children; i++) {
1184  assert(
1185  &mode->pb_type_children[i] == pb_graph_children_nodes[i][0].pb_type);
1186  if (0
1187  == strcmp(mode->pb_type_children[i].name,
1188  tokens[*token_index].data)) {
1189  pb_node_array = pb_graph_children_nodes[i];
1190  max_pb_node_array = mode->pb_type_children[i].num_pb;
1191  found = TRUE;
1192  (*token_index)++;
1193 
1194  if (tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) {
1195  (*token_index)++;
1196  if (!checkTokenType(tokens[*token_index], TOKEN_INT)) {
1197  return FALSE;
1198  }
1199  pb_msb = my_atoi(tokens[*token_index].data);
1200  (*token_index)++;
1201  if (!checkTokenType(tokens[*token_index], TOKEN_COLON)) {
1202  if (!checkTokenType(tokens[*token_index],
1204  return FALSE;
1205  }
1206  pb_lsb = pb_msb;
1207  (*token_index)++;
1208  } else {
1209  (*token_index)++;
1210  if (!checkTokenType(tokens[*token_index], TOKEN_INT)) {
1211  return FALSE;
1212  }
1213  pb_lsb = my_atoi(tokens[*token_index].data);
1214  (*token_index)++;
1215  if (!checkTokenType(tokens[*token_index],
1217  return FALSE;
1218  }
1219  (*token_index)++;
1220  }
1221  } else {
1222  pb_msb = pb_node_array[0].pb_type->num_pb - 1;
1223  pb_lsb = 0;
1224  }
1225  break;
1226  }
1227  }
1228  }
1229 
1230  if (!found) {
1231  vpr_printf(TIO_MESSAGE_ERROR,
1232  "[LINE %d] Unknown pb_type name %s, not defined in namespace of mode %s\n",
1233  line_num, tokens[*token_index].data, mode->name);
1234  return FALSE;
1235  }
1236 
1237  found = FALSE;
1238 
1239  if (!checkTokenType(tokens[*token_index], TOKEN_DOT)) {
1240  return FALSE;
1241  }
1242  (*token_index)++;
1243  if (!checkTokenType(tokens[*token_index], TOKEN_STRING)) {
1244  return FALSE;
1245  }
1246 
1247  /* parse ports and port pins of pb */
1248  port_name = tokens[*token_index].data;
1249 
1250  (*token_index)++;
1251  if (tokens[*token_index].type == TOKEN_OPEN_SQUARE_BRACKET) {
1252  (*token_index)++;
1253  if (!checkTokenType(tokens[*token_index], TOKEN_INT)) {
1254  return FALSE;
1255  }
1256  pin_msb = my_atoi(tokens[*token_index].data);
1257  (*token_index)++;
1258  if (!checkTokenType(tokens[*token_index], TOKEN_COLON)) {
1259  if (!checkTokenType(tokens[*token_index],
1261  return FALSE;
1262  }
1263  pin_lsb = pin_msb;
1264  (*token_index)++;
1265  } else {
1266  (*token_index)++;
1267  if (!checkTokenType(tokens[*token_index], TOKEN_INT)) {
1268  return FALSE;
1269  }
1270  pin_lsb = my_atoi(tokens[*token_index].data);
1271  (*token_index)++;
1272  if (!checkTokenType(tokens[*token_index],
1274  return FALSE;
1275  }
1276  (*token_index)++;
1277  }
1278  } else {
1279  if (pb_lsb < 0 || pb_lsb >= max_pb_node_array) {
1280  vpr_printf(TIO_MESSAGE_ERROR,
1281  "[LINE %d] pb %d out of range [%d,%d]\n", line_num, pb_lsb,
1282  max_pb_node_array - 1, 0);
1283  exit(1);
1284  }
1285  if (get_pb_graph_pin_from_name(port_name, &pb_node_array[pb_lsb],
1286  0) == NULL) {
1287  vpr_printf(TIO_MESSAGE_ERROR,
1288  "[LINE %d] failed to find port name %s\n", line_num,
1289  port_name);
1290  exit(1);
1291  }
1292  iport =
1293  get_pb_graph_pin_from_name(port_name, &pb_node_array[pb_lsb], 0)->port;
1294  pin_msb = iport->num_pins - 1;
1295  pin_lsb = 0;
1296  }
1297  (*token_index)--;
1298 
1299  if (pb_msb < pb_lsb) {
1300  add_or_subtract_pb = -1;
1301  } else {
1302  add_or_subtract_pb = 1;
1303  }
1304 
1305  if (pin_msb < pin_lsb) {
1306  add_or_subtract_pin = -1;
1307  } else {
1308  add_or_subtract_pin = 1;
1309  }
1310  *num_pins += (abs(pb_msb - pb_lsb) + 1) * (abs(pin_msb - pin_lsb) + 1);
1311  *pb_graph_pins = (t_pb_graph_pin**) my_calloc(*num_pins,
1312  sizeof(t_pb_graph_pin *));
1313  i = j = 0;
1314 
1315  ipb = pb_lsb;
1316 
1317  while (ipb != pb_msb + add_or_subtract_pin) {
1318  ipin = pin_lsb;
1319  j = 0;
1320  while (ipin != pin_msb + add_or_subtract_pin) {
1321  if (ipb < 0 || ipb >= max_pb_node_array) {
1322  vpr_printf(TIO_MESSAGE_ERROR,
1323  "[LINE %d] pb %d out of range [%d,%d]\n", line_num, ipb,
1324  max_pb_node_array - 1, 0);
1325  exit(1);
1326  }
1327  (*pb_graph_pins)[i * (abs(pin_msb - pin_lsb) + 1) + j] =
1328  get_pb_graph_pin_from_name(port_name, &pb_node_array[ipb],
1329  ipin);
1330  if ((*pb_graph_pins)[i * (abs(pin_msb - pin_lsb) + 1) + j] == NULL ) {
1331  vpr_printf(TIO_MESSAGE_ERROR,
1332  "[LINE %d] Pin %s.%s[%d] cannot be found\n", line_num,
1333  pb_node_array[ipb].pb_type->name, port_name, ipin);
1334  exit(1);
1335  }
1336  iport =
1337  (*pb_graph_pins)[i * (abs(pin_msb - pin_lsb) + 1) + j]->port;
1338  if (!iport) {
1339  return FALSE;
1340  }
1341 
1342  /* Error checking before assignment */
1343  if (interconnect_error_check) {
1344  if (pb_node_array == pb_graph_parent_node) {
1345  if (is_input_to_interc) {
1346  if (iport->type != IN_PORT) {
1347  vpr_printf(TIO_MESSAGE_ERROR,
1348  "[LINE %d] input to interconnect from parent is not an input or clock pin\n",
1349  line_num);
1350  return FALSE;
1351  }
1352  } else {
1353  if (iport->type != OUT_PORT) {
1354  vpr_printf(TIO_MESSAGE_ERROR,
1355  "[LINE %d] output from interconnect from parent is not an input or clock pin\n",
1356  line_num);
1357  return FALSE;
1358  }
1359  }
1360  } else {
1361  if (is_input_to_interc) {
1362  if (iport->type != OUT_PORT) {
1363  vpr_printf(TIO_MESSAGE_ERROR,
1364  "[LINE %d] output from interconnect from parent is not an input or clock pin\n",
1365  line_num);
1366  return FALSE;
1367  }
1368  } else {
1369  if (iport->type != IN_PORT) {
1370  vpr_printf(TIO_MESSAGE_ERROR,
1371  "[LINE %d] input to interconnect from parent is not an input or clock pin\n",
1372  line_num);
1373  return FALSE;
1374  }
1375  }
1376  }
1377  }
1378 
1379  /* load pb_graph_pin for pin */
1380 
1381  ipin += add_or_subtract_pin;
1382  j++;
1383  }
1384  i++;
1385  ipb += add_or_subtract_pb;
1386  }
1387 
1388  assert((abs(pb_msb - pb_lsb) + 1) * (abs(pin_msb - pin_lsb) + 1) == i * j);
1389 
1390  return TRUE;
1391 }
1392 
1393 static t_pb_graph_pin * get_pb_graph_pin_from_name(INP const char * port_name,
1394  INP const t_pb_graph_node * pb, INP int pin) {
1395  int i;
1396 
1397  for (i = 0; i < pb->num_input_ports; i++) {
1398  if (0 == strcmp(port_name, pb->input_pins[i][0].port->name)) {
1399  if (pin < pb->input_pins[i][0].port->num_pins) {
1400  return &pb->input_pins[i][pin];
1401  } else {
1402  return NULL ;
1403  }
1404  }
1405  }
1406  for (i = 0; i < pb->num_output_ports; i++) {
1407  if (0 == strcmp(port_name, pb->output_pins[i][0].port->name)) {
1408  if (pin < pb->output_pins[i][0].port->num_pins) {
1409  return &pb->output_pins[i][pin];
1410  } else {
1411  return NULL ;
1412  }
1413  }
1414  }
1415  for (i = 0; i < pb->num_clock_ports; i++) {
1416  if (0 == strcmp(port_name, pb->clock_pins[i][0].port->name)) {
1417  if (pin < pb->clock_pins[i][0].port->num_pins) {
1418  return &pb->clock_pins[i][pin];
1419  } else {
1420  return NULL ;
1421  }
1422  }
1423  }
1424  return NULL ;
1425 }
1426 
1428  int i, j, k, m, icapacity;
1429  int num_sides;
1430  int side_index;
1431  int pin_num;
1432  int count;
1433 
1434  int *num_pb_graph_node_pins; /* number of pins in a set [0..num_sets-1] */
1435  int num_pb_graph_node_sets;
1436  t_pb_graph_pin*** pb_graph_node_pins;
1437 
1438  num_sides = 2 * (type->height + 1);
1439  side_index = 0;
1440  count = 0;
1441 
1443  pin_num = 0;
1444  /* evenly distribute pins starting at bottom left corner */
1445  for (j = 0; j < 4; j++) {
1446  for (i = 0; i < type->height; i++) {
1447  if (j == TOP && i != type->height - 1) {
1448  continue;
1449  }
1450  if (j == BOTTOM && i != 0) {
1451  continue;
1452  }
1453  for (k = 0; k < (type->num_pins / num_sides) + 1; k++) {
1454  pin_num = side_index + k * num_sides;
1455  if (pin_num < type->num_pins) {
1456  type->pinloc[i][j][pin_num] = 1;
1457  type->pin_height[pin_num] = i;
1458  count++;
1459  }
1460  }
1461  side_index++;
1462  }
1463  }
1464  assert(side_index == num_sides);
1465  assert(count == type->num_pins);
1466  } else {
1468  for (i = 0; i < type->height; i++) {
1469  for (j = 0; j < 4; j++) {
1470  if (j == TOP && i != type->height - 1) {
1471  continue;
1472  }
1473  if (j == BOTTOM && i != 0) {
1474  continue;
1475  }
1476  for (k = 0; k < type->num_pin_loc_assignments[i][j]; k++) {
1477  pb_graph_node_pins =
1479  type->pb_type->modes[0].interconnect[0].line_num,
1480  type->pb_graph_head,
1482  type->pin_loc_assignments[i][j][k],
1483  &num_pb_graph_node_pins,
1484  &num_pb_graph_node_sets, FALSE, FALSE);
1485  assert(num_pb_graph_node_sets == 1);
1486 
1487  for (m = 0; m < num_pb_graph_node_pins[0]; m++) {
1488  pin_num =
1489  pb_graph_node_pins[0][m]->pin_count_in_cluster;
1490  assert(pin_num < type->num_pins / type->capacity);
1491  for (icapacity = 0; icapacity < type->capacity;
1492  icapacity++) {
1493  type->pinloc[i][j][pin_num
1494  + icapacity * type->num_pins
1495  / type->capacity] = 1;
1496  type->pin_height[pin_num] = i;
1497  assert(count < type->num_pins);
1498  }
1499  }
1500  free(pb_graph_node_pins[0]);
1501  free(pb_graph_node_pins);
1502  free(num_pb_graph_node_pins);
1503  }
1504  }
1505  }
1506  }
1507 }
1508 
1509 static void echo_pb_rec(const INP t_pb_graph_node *pb_graph_node, INP int level,
1510  INP FILE *fp) {
1511  int i, j, k;
1512 
1513  print_tabs(fp, level);
1514  fprintf(fp, "Physical Block: type \"%s\" index %d num_children %d\n",
1515  pb_graph_node->pb_type->name, pb_graph_node->placement_index,
1516  pb_graph_node->pb_type->num_pb);
1517 
1518  if (pb_graph_node->parent_pb_graph_node) {
1519  print_tabs(fp, level + 1);
1520  fprintf(fp, "Parent Block: type \"%s\" index %d \n",
1521  pb_graph_node->parent_pb_graph_node->pb_type->name,
1522  pb_graph_node->parent_pb_graph_node->placement_index);
1523  }
1524 
1525  print_tabs(fp, level);
1526  fprintf(fp, "Input Ports: total ports %d\n",
1527  pb_graph_node->num_input_ports);
1528  echo_pb_pins(pb_graph_node->input_pins, pb_graph_node->num_input_ports,
1529  level, fp);
1530  print_tabs(fp, level);
1531  fprintf(fp, "Output Ports: total ports %d\n",
1532  pb_graph_node->num_output_ports);
1533  echo_pb_pins(pb_graph_node->output_pins, pb_graph_node->num_output_ports,
1534  level, fp);
1535  print_tabs(fp, level);
1536  fprintf(fp, "Clock Ports: total ports %d\n",
1537  pb_graph_node->num_clock_ports);
1538  echo_pb_pins(pb_graph_node->clock_pins, pb_graph_node->num_clock_ports,
1539  level, fp);
1540  print_tabs(fp, level);
1541  for (i = 0; i < pb_graph_node->num_input_pin_class; i++) {
1542  fprintf(fp, "Input class %d: %d pins, ", i,
1543  pb_graph_node->input_pin_class_size[i]);
1544  }
1545  fprintf(fp, "\n");
1546  print_tabs(fp, level);
1547  for (i = 0; i < pb_graph_node->num_output_pin_class; i++) {
1548  fprintf(fp, "Output class %d: %d pins, ", i,
1549  pb_graph_node->output_pin_class_size[i]);
1550  }
1551  fprintf(fp, "\n");
1552 
1553  if (pb_graph_node->pb_type->num_modes > 0) {
1554  print_tabs(fp, level);
1555  fprintf(fp, "Children:\n");
1556  }
1557  for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
1558  for (j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
1559  j++) {
1560  for (k = 0;
1561  k
1562  < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
1563  k++) {
1564  echo_pb_rec(&pb_graph_node->child_pb_graph_nodes[i][j][k],
1565  level + 1, fp);
1566  }
1567  }
1568  }
1569 }
1570 
1571 static void echo_pb_pins(INP t_pb_graph_pin **pb_graph_pins, INP int num_ports,
1572  INP int level, INP FILE * fp) {
1573  int i, j, k, m;
1574  t_port *port;
1575 
1576  print_tabs(fp, level);
1577 
1578  for (i = 0; i < num_ports; i++) {
1579  port = pb_graph_pins[i][0].port;
1580  print_tabs(fp, level);
1581  fprintf(fp, "Port \"%s\": num_pins %d type %d parent name \"%s\"\n",
1582  port->name, port->num_pins, port->type,
1583  port->parent_pb_type->name);
1584 
1585  for (j = 0; j < port->num_pins; j++) {
1586  print_tabs(fp, level + 1);
1587  assert(j == pb_graph_pins[i][j].pin_number);
1588  assert(pb_graph_pins[i][j].port == port);
1589  fprintf(fp,
1590  "Pin %d port name \"%s\" num input edges %d num output edges %d parent type \"%s\" parent index %d\n",
1591  pb_graph_pins[i][j].pin_number,
1592  pb_graph_pins[i][j].port->name,
1593  pb_graph_pins[i][j].num_input_edges,
1594  pb_graph_pins[i][j].num_output_edges,
1595  pb_graph_pins[i][j].parent_node->pb_type->name,
1596  pb_graph_pins[i][j].parent_node->placement_index);
1597  print_tabs(fp, level + 2);
1598  if (pb_graph_pins[i][j].parent_node->pb_type->num_modes == 0) {
1599  fprintf(fp, "pin class (depth, pin class): ");
1600  for (k = 0; k < pb_graph_pins[i][j].parent_node->pb_type->depth;
1601  k++) {
1602  fprintf(fp, "(%d %d), ", k,
1603  pb_graph_pins[i][j].parent_pin_class[k]);
1604  }
1605  fprintf(fp, "\n");
1606  if (pb_graph_pins[i][j].port->type == OUT_PORT) {
1607  for (k = 0;
1608  k < pb_graph_pins[i][j].parent_node->pb_type->depth;
1609  k++) {
1610  print_tabs(fp, level + 2);
1611  fprintf(fp,
1612  "connectable input pins within depth %d: %d\n",
1613  k,
1614  pb_graph_pins[i][j].num_connectable_primtive_input_pins[k]);
1615  for (m = 0;
1616  m
1617  < pb_graph_pins[i][j].num_connectable_primtive_input_pins[k];
1618  m++) {
1619  print_tabs(fp, level + 3);
1620  fprintf(fp, "pb_graph_node %s[%d].%s[%d] \n",
1621  pb_graph_pins[i][j].list_of_connectable_input_pin_ptrs[k][m]->parent_node->pb_type->name,
1622  pb_graph_pins[i][j].list_of_connectable_input_pin_ptrs[k][m]->parent_node->placement_index,
1623  pb_graph_pins[i][j].list_of_connectable_input_pin_ptrs[k][m]->port->name,
1624  pb_graph_pins[i][j].list_of_connectable_input_pin_ptrs[k][m]->pin_number);
1625  }
1626  }
1627  }
1628  } else {
1629  fprintf(fp, "pin class %d \n", pb_graph_pins[i][j].pin_class);
1630  }
1631  for (k = 0; k < pb_graph_pins[i][j].num_input_edges; k++) {
1632  print_tabs(fp, level + 2);
1633  fprintf(fp, "Input edge %d num inputs %d num outputs %d\n", k,
1634  pb_graph_pins[i][j].input_edges[k]->num_input_pins,
1635  pb_graph_pins[i][j].input_edges[k]->num_output_pins);
1636  print_tabs(fp, level + 3);
1637  fprintf(fp, "Input edge inputs\n");
1638  for (m = 0;
1639  m < pb_graph_pins[i][j].input_edges[k]->num_input_pins;
1640  m++) {
1641  print_tabs(fp, level + 3);
1642  fprintf(fp, "pin number %d port_name \"%s\"\n",
1643  pb_graph_pins[i][j].input_edges[k]->input_pins[m]->pin_number,
1644  pb_graph_pins[i][j].input_edges[k]->input_pins[m]->port->name);
1645  }
1646  print_tabs(fp, level + 3);
1647  fprintf(fp, "Input edge outputs\n");
1648  for (m = 0;
1649  m < pb_graph_pins[i][j].input_edges[k]->num_output_pins;
1650  m++) {
1651  print_tabs(fp, level + 3);
1652  fprintf(fp,
1653  "pin number %d port_name \"%s\" parent type \"%s\" parent index %d\n",
1654  pb_graph_pins[i][j].input_edges[k]->output_pins[m]->pin_number,
1655  pb_graph_pins[i][j].input_edges[k]->output_pins[m]->port->name,
1656  pb_graph_pins[i][j].input_edges[k]->output_pins[m]->parent_node->pb_type->name,
1657  pb_graph_pins[i][j].input_edges[k]->output_pins[m]->parent_node->placement_index);
1658  }
1659  }
1660  for (k = 0; k < pb_graph_pins[i][j].num_output_edges; k++) {
1661  print_tabs(fp, level + 2);
1662  fprintf(fp, "Output edge %d num inputs %d num outputs %d\n", k,
1663  pb_graph_pins[i][j].output_edges[k]->num_input_pins,
1664  pb_graph_pins[i][j].output_edges[k]->num_output_pins);
1665  print_tabs(fp, level + 3);
1666  fprintf(fp, "Output edge inputs\n");
1667  for (m = 0;
1668  m < pb_graph_pins[i][j].output_edges[k]->num_input_pins;
1669  m++) {
1670  print_tabs(fp, level + 3);
1671  fprintf(fp, "pin number %d port_name \"%s\"\n",
1672  pb_graph_pins[i][j].output_edges[k]->input_pins[m]->pin_number,
1673  pb_graph_pins[i][j].output_edges[k]->input_pins[m]->port->name);
1674  }
1675  print_tabs(fp, level + 3);
1676  fprintf(fp, "Output edge outputs\n");
1677  for (m = 0;
1678  m < pb_graph_pins[i][j].output_edges[k]->num_output_pins;
1679  m++) {
1680  print_tabs(fp, level + 3);
1681  fprintf(fp,
1682  "pin number %d port_name \"%s\" parent type \"%s\" parent index %d\n",
1683  pb_graph_pins[i][j].output_edges[k]->output_pins[m]->pin_number,
1684  pb_graph_pins[i][j].output_edges[k]->output_pins[m]->port->name,
1685  pb_graph_pins[i][j].output_edges[k]->output_pins[m]->parent_node->pb_type->name,
1686  pb_graph_pins[i][j].output_edges[k]->output_pins[m]->parent_node->placement_index);
1687  }
1688  }
1689  }
1690  }
1691 }
1692 
static void alloc_and_load_pb_graph(INOUTP t_pb_graph_node *pb_graph_node, INP t_pb_graph_node *parent_pb_graph_node, INP t_pb_type *pb_type, INP int index, boolean load_power_structures)
t_interconnect * interconnect
void load_pb_graph_pin_to_pin_annotations(INOUTP t_pb_graph_node *pb_graph_node)
FILE * my_fopen(const char *fname, const char *flag, int prompt)
Definition: util.c:54
char * name
boolean checkTokenType(INP t_token token, OUTP enum e_token_type token_type)
Definition: token.c:126
int num_pins
static void alloc_and_load_complete_interc_edges(INP t_interconnect *interconnect, INOUTP t_pb_graph_pin ***input_pb_graph_node_pin_ptrs, INP int num_input_sets, INP int *num_input_ptrs, INOUTP t_pb_graph_pin ***output_pb_graph_node_pin_ptrs, INP int num_output_sets, INP int *num_output_ptrs)
struct s_pb_type * pb_type_children
static struct s_linked_vptr * num_edges_head
Definition: pb_type_graph.c:26
t_type_ptr EMPTY_TYPE
Definition: globals.c:41
static struct s_linked_vptr * edges_head
Definition: pb_type_graph.c:25
static void alloc_and_load_direct_interc_edges(INP t_interconnect *interconnect, INOUTP t_pb_graph_pin ***input_pb_graph_node_pin_ptrs, INP int num_input_sets, INP int *num_input_ptrs, INOUTP t_pb_graph_pin ***output_pb_graph_node_pin_ptrs, INP int num_output_sets, INP int *num_output_ptrs)
t_mode * modes
t_pb_graph_pin ** output_pins
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
enum PORTS type
static void alloc_and_load_interconnect_pins(t_interconnect_pins *interc_pins, t_interconnect *interconnect, t_pb_graph_pin ***input_pins, int num_input_sets, int *num_input_pins, t_pb_graph_pin ***output_pins, int num_output_sets, int *num_output_pins)
t_token * GetTokensFromString(INP const char *inString, OUTP int *num_tokens)
Definition: token.c:18
void alloc_and_load_all_pb_graphs(boolean load_power_structures)
Definition: pb_type_graph.c:89
t_interconnect * interconnect
enum e_pin_location_distr pin_location_distribution
#define INOUTP
Definition: util.h:21
t_interconnect * interconnect
Definition: util.h:12
struct s_pb_graph_pin *** output_pins
static void * my_malloc(int ibytes)
Definition: graphics.c:499
static int pin_count_in_cluster
Definition: pb_type_graph.c:24
static void echo_pb_pins(INP t_pb_graph_pin **pb_graph_pins, INP int num_ports, INP int level, INP FILE *fp)
void echo_pb_graph(char *filename)
#define INP
Definition: util.h:19
static void alloc_and_load_pin_locations_from_pb_graph(t_type_descriptor *type)
char * name
static int check_pb_graph(void)
static void free_pb_graph(INOUTP t_pb_graph_node *pb_graph_node)
char **** pin_loc_assignments
enum e_interconnect type
struct s_pb_graph_node *** child_pb_graph_nodes
struct s_linked_vptr * next
Definition: util.h:36
int num_pb_type_children
void * data_vptr
Definition: util.h:35
struct s_pb_type * pb_type
t_pb_graph_pin ** input_pins
void load_pin_classes_in_pb_graph_head(INOUTP t_pb_graph_node *pb_graph_node)
struct s_pb_type * pb_type
struct s_pb_type * parent_pb_type
int num_types
Definition: globals.c:37
int ** num_pin_loc_assignments
static void * my_realloc(void *memblk, int ibytes)
Definition: graphics.c:512
void free_all_pb_graph_nodes(void)
t_pb_graph_pin *** alloc_and_load_port_pin_ptrs_from_string(INP int line_num, INP const t_pb_graph_node *pb_graph_parent_node, INP t_pb_graph_node **pb_graph_children_nodes, INP const char *port_string, OUTP int **num_ptrs, OUTP int *num_sets, INP boolean is_input_to_interc, INP boolean interconnect_error_check)
Definition: slre.c:50
struct s_pb_graph_pin *** input_pins
t_pb_graph_node * pb_graph_head
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
#define OUTP
Definition: util.h:20
Definition: token.h:22
static void echo_pb_rec(INP const t_pb_graph_node *pb, INP int level, INP FILE *fp)
void freeTokens(INP t_token *tokens, INP int num_tokens)
Definition: token.c:93
static void print_tabs(FILE *fpout, int num_tabs)
int my_atoi(const char *str)
Definition: util.c:116
messagelogger vpr_printf
Definition: util.c:17
static boolean realloc_and_load_pb_graph_pin_ptrs_at_var(INP int line_num, INP const t_pb_graph_node *pb_graph_parent_node, INP t_pb_graph_node **pb_graph_children_nodes, INP boolean interconnect_error_check, INP boolean is_input_to_interc, INP const t_token *tokens, INOUTP int *token_index, INOUTP int *num_pins, OUTP t_pb_graph_pin ***pb_graph_pins)
t_interconnect_power * interconnect_power
static void alloc_and_load_mode_interconnect(INOUTP t_pb_graph_node *pb_graph_parent_node, INOUTP t_pb_graph_node **pb_graph_children_nodes, INP const t_mode *mode, boolean load_power_structures)
static t_pb_graph_pin * get_pb_graph_pin_from_name(INP const char *port_name, INP const t_pb_graph_node *pb, INP int pin)
Definition: util.h:12
static void alloc_and_load_mux_interc_edges(INP t_interconnect *interconnect, INOUTP t_pb_graph_pin ***input_pb_graph_node_pin_ptrs, INP int num_input_sets, INP int *num_input_ptrs, INOUTP t_pb_graph_pin ***output_pb_graph_node_pin_ptrs, INP int num_output_sets, INP int *num_output_ptrs)