VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
cluster_feasibility_filter.c
Go to the documentation of this file.
1 /*
2  Feasibility filter used during packing that determines if various necessary conditions for legality are met
3 
4  Important for 2 reasons:
5  1) Quickly reject cases that are bad so that we don't waste time exploring useless cases in packing
6  2) Robustness issue. During packing, we have a limited size queue to store candidates to try to pack. A good filter helps keep that queue filled with candidates likely to pass.
7 
8  1st major filter: Pin counting based on pin classes
9  Rationale: If the number of a particular gruop of pins supplied by the pb_graph_node in the architecture is insufficient to meet a candidate packing solution's demand for that group of pins, then that
10  candidate solution is for sure invalid without any further legalization checks. For example, if a candidate solution requires 2 clock pins but the architecture only has one clock, then that solution
11  can't be legal.
12 
13  Implementation details:
14  a) Definition of a pin class - If there exists a path (ignoring directionality of connections) from pin A to pin B and pin A and pin B are of the same type (input, output, or clock), then pin A and pin B are in the same pin class. Otherwise, pin A and pin B are in different pin classes.
15  b) Code Identifies pin classes. Given a candidate solution
16 
17  TODO: May 30, 2012 Jason Luu - Must take into consideration modes when doing pin counting. For fracturable LUTs FI = 5, the soft logic block sees 6 pins instead of 5 pins for the dual LUT mode messing up the pin counter. The packer still produces correct results but runs slower than its best (experiment on a modified architecture file that forces correct pin counting shows 40x speedup vs VPR 6.0 as opposed to 3x speedup at the time)
18 
19  Author: Jason Luu
20  Date: May 16, 2012
21 
22 
23  */
24 #include <assert.h>
25 
26 #include "read_xml_arch_file.h"
27 #include "util.h"
28 #include "vpr_types.h"
29 #include "globals.h"
30 #include "hash.h"
32 #include "vpr_utils.h"
33 #include "ReadOptions.h"
34 
35 /* header functions that identify pin classes */
37  INOUTP t_pb_graph_node *pb_graph_node);
38 static int get_max_depth_of_pb_graph_node(INP t_pb_graph_node *pb_graph_node);
39 static void load_pin_class_by_depth(INOUTP t_pb_graph_node *pb_graph_node,
40  INP int depth, OUTP int *input_count, OUTP int *output_count);
42  INOUTP t_pb_graph_node *pb_graph_node);
44  INOUTP t_pb_graph_pin *current_pb_graph_pin,
45  INOUTP t_pb_graph_pin *reference_pin, INP int depth);
47  INOUTP t_pb_graph_pin *current_pb_graph_pin);
49  INOUTP t_pb_graph_node *pb_graph_node);
51  INOUTP t_pb_graph_pin *current_pb_graph_pin,
52  INP t_pb_graph_pin *reference_pb_graph_pin, INP int depth,
53  OUTP int *input_count, OUTP int *output_count);
54 static void sum_pin_class(INOUTP t_pb_graph_node *pb_graph_node);
55 
56 static void discover_all_forced_connections(INOUTP t_pb_graph_node *pb_graph_node);
57 static boolean is_forced_connection(INP t_pb_graph_pin *pb_graph_pin);
58 
59 
60 /* Identify all pin class information for complex block
61  */
63  int i, depth, input_count, output_count;
64 
65  /* Allocate memory for primitives */
67 
68  /* Load pin classes */
69  depth = get_max_depth_of_pb_graph_node(pb_graph_node);
70  for (i = 0; i < depth; i++) {
71  input_count = output_count = 0;
72  reset_pin_class_scratch_pad_rec(pb_graph_node);
73  load_pin_class_by_depth(pb_graph_node, i, &input_count, &output_count);
74  }
75 
76  /* Load internal output-to-input connections within each cluster */
77  reset_pin_class_scratch_pad_rec(pb_graph_node);
79  discover_all_forced_connections(pb_graph_node);
80 }
81 
82 /**
83  * Recursive function to allocate memory space for pin classes in primitives
84  */
86  INOUTP t_pb_graph_node *pb_graph_node) {
87  int i, j, k;
88 
89  /* If primitive, allocate space, else go to primitive */
90  if (pb_graph_node->pb_type->num_modes == 0) {
91  /* allocate space */
92  for (i = 0; i < pb_graph_node->num_input_ports; i++) {
93  for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
94  pb_graph_node->input_pins[i][j].parent_pin_class =
95  (int *) my_calloc(pb_graph_node->pb_type->depth,
96  sizeof(int*));
97  for (k = 0; k < pb_graph_node->pb_type->depth; k++) {
98  pb_graph_node->input_pins[i][j].parent_pin_class[k] = OPEN;
99  }
100  }
101  }
102  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
103  for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
104  pb_graph_node->output_pins[i][j].parent_pin_class =
105  (int *) my_calloc(pb_graph_node->pb_type->depth,
106  sizeof(int*));
107  pb_graph_node->output_pins[i][j].list_of_connectable_input_pin_ptrs =
109  pb_graph_node->pb_type->depth,
110  sizeof(t_pb_graph_pin**));
111  pb_graph_node->output_pins[i][j].num_connectable_primtive_input_pins =
112  (int*) my_calloc(pb_graph_node->pb_type->depth,
113  sizeof(int));
114  for (k = 0; k < pb_graph_node->pb_type->depth; k++) {
115  pb_graph_node->output_pins[i][j].parent_pin_class[k] = OPEN;
116  }
117  }
118  }
119  for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
120  for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
121  pb_graph_node->clock_pins[i][j].parent_pin_class =
122  (int *) my_calloc(pb_graph_node->pb_type->depth,
123  sizeof(int*));
124  for (k = 0; k < pb_graph_node->pb_type->depth; k++) {
125  pb_graph_node->clock_pins[i][j].parent_pin_class[k] = OPEN;
126  }
127  }
128  }
129  } else {
130  for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
131  for (j = 0;
132  j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
133  j++) {
134  for (k = 0;
135  k
136  < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
137  k++) {
139  &pb_graph_node->child_pb_graph_nodes[i][j][k]);
140  }
141  }
142  }
143  }
144 }
145 
146 /* determine maximum depth of pb_graph_node */
148  int i, j, k;
149  int max_depth, depth;
150 
151  max_depth = 0;
152 
153  /* If primitive, allocate space, else go to primitive */
154  if (pb_graph_node->pb_type->num_modes == 0) {
155  return pb_graph_node->pb_type->depth;
156  } else {
157  for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
158  for (j = 0;
159  j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
160  j++) {
161  for (k = 0;
162  k
163  < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
164  k++) {
166  &pb_graph_node->child_pb_graph_nodes[i][j][k]);
167  if (depth > max_depth) {
168  max_depth = depth;
169  }
170  }
171  }
172  }
173  }
174 
175  return max_depth;
176 }
177 
179  INOUTP t_pb_graph_node *pb_graph_node) {
180  int i, j, k;
181 
182  for (i = 0; i < pb_graph_node->num_input_ports; i++) {
183  for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
184  pb_graph_node->input_pins[i][j].scratch_pad = OPEN;
185  }
186  }
187  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
188  for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
189  pb_graph_node->output_pins[i][j].scratch_pad = OPEN;
190  }
191  }
192  for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
193  for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
194  pb_graph_node->clock_pins[i][j].scratch_pad = OPEN;
195  }
196  }
197 
198  for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
199  for (j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
200  j++) {
201  for (k = 0;
202  k
203  < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
204  k++) {
206  &pb_graph_node->child_pb_graph_nodes[i][j][k]);
207  }
208  }
209  }
210 }
211 
212 /* load pin class based on limited depth */
213 static void load_pin_class_by_depth(INOUTP t_pb_graph_node *pb_graph_node,
214  INP int depth, OUTP int *input_count, OUTP int *output_count) {
215  int i, j, k;
216 
217  if (pb_graph_node->pb_type->num_modes == 0) {
218  if (pb_graph_node->pb_type->depth > depth) {
219  /* At primitive, determine which pin class each of its pins belong to */
220  for (i = 0; i < pb_graph_node->num_input_ports; i++) {
221  for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
222  if (pb_graph_node->input_pins[i][j].parent_pin_class[depth]
223  == OPEN) {
225  &pb_graph_node->input_pins[i][j],
226  &pb_graph_node->input_pins[i][j], depth,
227  input_count, output_count);
228  (*input_count)++;
229  }
230  }
231  }
232  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
233  for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
234  if (pb_graph_node->output_pins[i][j].parent_pin_class[depth]
235  == OPEN) {
237  &pb_graph_node->output_pins[i][j],
238  &pb_graph_node->output_pins[i][j], depth,
239  input_count, output_count);
240  (*output_count)++;
241  }
242  }
243  }
244  for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
245  for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
246  if (pb_graph_node->clock_pins[i][j].parent_pin_class[depth]
247  == OPEN) {
249  &pb_graph_node->clock_pins[i][j],
250  &pb_graph_node->clock_pins[i][j], depth,
251  input_count, output_count);
252  (*input_count)++;
253  }
254  }
255  }
256  }
257  }
258 
259  if (pb_graph_node->pb_type->depth == depth) {
260  /* Load pin classes for all pb_graph_nodes of this depth, therefore, at a particular pb_graph_node of this depth, set # of pin classes to be 0 */
261  *input_count = 0;
262  *output_count = 0;
263  for (i = 0; i < pb_graph_node->num_input_ports; i++) {
264  for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
265  pb_graph_node->input_pins[i][j].pin_class = OPEN;
266  }
267  }
268  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
269  for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
270  pb_graph_node->output_pins[i][j].pin_class = OPEN;
271  }
272  }
273  for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
274  for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
275  pb_graph_node->clock_pins[i][j].pin_class = OPEN;
276  }
277  }
278  }
279 
280  /* Expand down to primitives */
281  for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
282  for (j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
283  j++) {
284  for (k = 0;
285  k
286  < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
287  k++) {
289  &pb_graph_node->child_pb_graph_nodes[i][j][k], depth,
290  input_count, output_count);
291  }
292  }
293  }
294 
295  if (pb_graph_node->pb_type->depth == depth
296  && pb_graph_node->pb_type->num_modes != 0) {
297  /* Record pin class information for cluster */
298  pb_graph_node->num_input_pin_class = *input_count + 1; /* number of input pin classes discovered + 1 for primitive inputs not reachable from cluster input pins */
299  pb_graph_node->input_pin_class_size = (int*) my_calloc(*input_count + 1,
300  sizeof(int));
301  pb_graph_node->num_output_pin_class = *output_count + 1; /* number of output pin classes discovered + 1 for primitive inputs not reachable from cluster input pins */
302  pb_graph_node->output_pin_class_size = (int*) my_calloc(*output_count + 1,
303  sizeof(int));
304  sum_pin_class(pb_graph_node);
305  }
306 
307 }
308 
309 /**
310  * Load internal output-to-input connections within each cluster
311  */
313  INOUTP t_pb_graph_node *pb_graph_node) {
314  int i, j, k;
315 
316  if (pb_graph_node->pb_type->num_modes == 0) {
317  /* If this is a primitive, discover what input pins the output pins can connect to */
318  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
319  for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
320  for (k = 0; k < pb_graph_node->pb_type->depth; k++) {
322  &pb_graph_node->output_pins[i][j],
323  &pb_graph_node->output_pins[i][j], k);
325  &pb_graph_node->output_pins[i][j]);
326  }
327  }
328  }
329  }
330  /* Expand down to primitives */
331  for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
332  for (j = 0; j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
333  j++) {
334  for (k = 0;k < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
335  k++) {
337  &pb_graph_node->child_pb_graph_nodes[i][j][k]);
338  }
339  }
340  }
341 }
342 
343 /* Traverse outputs of output pin or primitive to see what input pins it reaches
344  Record list of input pins based on depth
345  */
347  INOUTP t_pb_graph_pin *current_pb_graph_pin,
348  INOUTP t_pb_graph_pin *reference_pin, INP int depth) {
349  int i;
350 
351  if (current_pb_graph_pin->scratch_pad == OPEN
352  && current_pb_graph_pin->parent_node->pb_type->depth > depth) {
353  current_pb_graph_pin->scratch_pad = 1;
354  for (i = 0; i < current_pb_graph_pin->num_output_edges; i++) {
355  assert(current_pb_graph_pin->output_edges[i]->num_output_pins == 1);
357  current_pb_graph_pin->output_edges[i]->output_pins[0],
358  reference_pin, depth);
359  }
360  if (current_pb_graph_pin->parent_node->pb_type->num_modes == 0
361  && current_pb_graph_pin->port->type == IN_PORT) {
362  reference_pin->num_connectable_primtive_input_pins[depth]++;
363  reference_pin->list_of_connectable_input_pin_ptrs[depth] =
365  reference_pin->list_of_connectable_input_pin_ptrs[depth],
366  reference_pin->num_connectable_primtive_input_pins[depth]
367  * sizeof(t_pb_graph_pin*));
368  reference_pin->list_of_connectable_input_pin_ptrs[depth][reference_pin->num_connectable_primtive_input_pins[depth]
369  - 1] = current_pb_graph_pin;
370  }
371  }
372 }
373 
374 /**
375  * Clear scratch_pad for all fanout of pin
376  */
378  INOUTP t_pb_graph_pin *current_pb_graph_pin) {
379  int i;
380  if (current_pb_graph_pin->scratch_pad != OPEN) {
381  current_pb_graph_pin->scratch_pad = OPEN;
382  for (i = 0; i < current_pb_graph_pin->num_output_edges; i++) {
383  assert(current_pb_graph_pin->output_edges[i]->num_output_pins == 1);
385  current_pb_graph_pin->output_edges[i]->output_pins[0]);
386  }
387  }
388 }
389 
390 /**
391  * Determine other primitive pins that belong to the same pin class as reference pin
392  */
394  INOUTP t_pb_graph_pin *current_pb_graph_pin,
395  INP t_pb_graph_pin *reference_pb_graph_pin, INP int depth,
396  OUTP int *input_count, OUTP int *output_count) {
397  int i;
398  int marker;
399  int active_pin_class;
400 
401  if (reference_pb_graph_pin->port->type == IN_PORT) {
402  marker = *input_count + 10;
403  active_pin_class = *input_count;
404  } else {
405  marker = -10 - *output_count;
406  active_pin_class = *output_count;
407  }
408  assert(reference_pb_graph_pin->parent_node->pb_type->num_modes == 0);
409  assert(current_pb_graph_pin->parent_node->pb_type->depth >= depth);
410  assert(current_pb_graph_pin->port->type != INOUT_PORT);
411  if (current_pb_graph_pin->scratch_pad != marker) {
412  if (current_pb_graph_pin->parent_node->pb_type->num_modes == 0) {
413  current_pb_graph_pin->scratch_pad = marker;
414  /* This is a primitive, determine what pins cans share the same pin class as the reference pin */
415  if (current_pb_graph_pin->parent_pin_class[depth] == OPEN
416  && reference_pb_graph_pin->port->is_clock
417  == current_pb_graph_pin->port->is_clock
418  && reference_pb_graph_pin->port->type
419  == current_pb_graph_pin->port->type) {
420  current_pb_graph_pin->parent_pin_class[depth] =
421  active_pin_class;
422  }
423  for (i = 0; i < current_pb_graph_pin->num_input_edges; i++) {
424  assert(
425  current_pb_graph_pin->input_edges[i]->num_input_pins == 1);
427  current_pb_graph_pin->input_edges[i]->input_pins[0],
428  reference_pb_graph_pin, depth, input_count,
429  output_count);
430  }
431  for (i = 0; i < current_pb_graph_pin->num_output_edges; i++) {
432  assert(
433  current_pb_graph_pin->output_edges[i]->num_output_pins == 1);
435  current_pb_graph_pin->output_edges[i]->output_pins[0],
436  reference_pb_graph_pin, depth, input_count,
437  output_count);
438  }
439  } else if (current_pb_graph_pin->parent_node->pb_type->depth == depth) {
440  current_pb_graph_pin->scratch_pad = marker;
441  if (current_pb_graph_pin->port->type == OUT_PORT) {
442  if (reference_pb_graph_pin->port->type == OUT_PORT) {
443  /* This cluster's output pin can be driven by primitive outputs belonging to this pin class */
444  current_pb_graph_pin->pin_class = active_pin_class;
445  }
446  for (i = 0; i < current_pb_graph_pin->num_input_edges; i++) {
447  assert(
448  current_pb_graph_pin->input_edges[i]->num_input_pins == 1);
450  current_pb_graph_pin->input_edges[i]->input_pins[0],
451  reference_pb_graph_pin, depth, input_count,
452  output_count);
453  }
454  }
455  if (current_pb_graph_pin->port->type == IN_PORT) {
456  if (reference_pb_graph_pin->port->type == IN_PORT) {
457  /* This cluster's input pin can drive the primitive input pins belonging to this pin class */
458  current_pb_graph_pin->pin_class = active_pin_class;
459  }
460  for (i = 0; i < current_pb_graph_pin->num_output_edges; i++) {
461  assert(
462  current_pb_graph_pin->output_edges[i]->num_output_pins == 1);
464  current_pb_graph_pin->output_edges[i]->output_pins[0],
465  reference_pb_graph_pin, depth, input_count,
466  output_count);
467  }
468  }
469  } else if (current_pb_graph_pin->parent_node->pb_type->depth > depth) {
470  /* Inside an intermediate cluster, traverse to either a primitive or to the cluster we're interested in populating */
471  current_pb_graph_pin->scratch_pad = marker;
472  for (i = 0; i < current_pb_graph_pin->num_input_edges; i++) {
473  assert(
474  current_pb_graph_pin->input_edges[i]->num_input_pins == 1);
476  current_pb_graph_pin->input_edges[i]->input_pins[0],
477  reference_pb_graph_pin, depth, input_count,
478  output_count);
479  }
480  for (i = 0; i < current_pb_graph_pin->num_output_edges; i++) {
481  assert(
482  current_pb_graph_pin->output_edges[i]->num_output_pins == 1);
484  current_pb_graph_pin->output_edges[i]->output_pins[0],
485  reference_pb_graph_pin, depth, input_count,
486  output_count);
487  }
488  }
489  }
490 }
491 
492 /* count up pin classes of the same number for the given cluster */
493 static void sum_pin_class(INOUTP t_pb_graph_node *pb_graph_node) {
494  int i, j;
495 
496  /* This is a primitive, for each pin in primitive, sum appropriate pin class */
497  for (i = 0; i < pb_graph_node->num_input_ports; i++) {
498  for (j = 0; j < pb_graph_node->num_input_pins[i]; j++) {
499  assert(
500  pb_graph_node->input_pins[i][j].pin_class < pb_graph_node->num_input_pin_class);
501  if (pb_graph_node->input_pins[i][j].pin_class == OPEN) {
502  vpr_printf(TIO_MESSAGE_WARNING, "%s[%d].%s[%d] unconnected pin in architecture.\n",
503  pb_graph_node->pb_type->name,
504  pb_graph_node->placement_index,
505  pb_graph_node->input_pins[i][j].port->name,
506  pb_graph_node->input_pins[i][j].pin_number);
507  continue;
508  }
509  pb_graph_node->input_pin_class_size[pb_graph_node->input_pins[i][j].pin_class]++;
510  }
511  }
512  for (i = 0; i < pb_graph_node->num_output_ports; i++) {
513  for (j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
514  assert(
515  pb_graph_node->output_pins[i][j].pin_class < pb_graph_node->num_output_pin_class);
516  if (pb_graph_node->output_pins[i][j].pin_class == OPEN) {
517  vpr_printf(TIO_MESSAGE_WARNING, "%s[%d].%s[%d] unconnected pin in architecture.\n",
518  pb_graph_node->pb_type->name,
519  pb_graph_node->placement_index,
520  pb_graph_node->output_pins[i][j].port->name,
521  pb_graph_node->output_pins[i][j].pin_number);
522  continue;
523  }
524  pb_graph_node->output_pin_class_size[pb_graph_node->output_pins[i][j].pin_class]++;
525  }
526  }
527  for (i = 0; i < pb_graph_node->num_clock_ports; i++) {
528  for (j = 0; j < pb_graph_node->num_clock_pins[i]; j++) {
529  assert(
530  pb_graph_node->clock_pins[i][j].pin_class < pb_graph_node->num_input_pin_class);
531  if (pb_graph_node->clock_pins[i][j].pin_class == OPEN) {
532  vpr_printf(TIO_MESSAGE_WARNING, "%s[%d].%s[%d] unconnected pin in architecture.\n",
533  pb_graph_node->pb_type->name,
534  pb_graph_node->placement_index,
535  pb_graph_node->clock_pins[i][j].port->name,
536  pb_graph_node->clock_pins[i][j].pin_number);
537  continue;
538  }
539  pb_graph_node->input_pin_class_size[pb_graph_node->clock_pins[i][j].pin_class]++;
540  }
541  }
542 }
543 
544 /* Recursively visit all pb_graph_pins and determine primitive output pins that connect to nothing else than one primitive input pin. If a net maps to this output pin, then the primitive corresponding to that input must be used */
546  int i, j, k;
547 
548  /* If primitive, allocate space, else go to primitive */
549  if (pb_graph_node->pb_type->num_modes == 0) {
550  for(i = 0; i < pb_graph_node->num_output_ports; i++) {
551  for(j = 0; j < pb_graph_node->num_output_pins[i]; j++) {
552  pb_graph_node->output_pins[i][j].is_forced_connection = is_forced_connection(&pb_graph_node->output_pins[i][j]);
553  }
554  }
555  } else {
556  for (i = 0; i < pb_graph_node->pb_type->num_modes; i++) {
557  for (j = 0;
558  j < pb_graph_node->pb_type->modes[i].num_pb_type_children;
559  j++) {
560  for (k = 0;
561  k < pb_graph_node->pb_type->modes[i].pb_type_children[j].num_pb;
562  k++) {
563  discover_all_forced_connections(&pb_graph_node->child_pb_graph_nodes[i][j][k]);
564  }
565  }
566  }
567  }
568 }
569 
570 /**
571  * Given an output pin, determine if it connects to only one input pin and nothing else.
572  */
573 static boolean is_forced_connection(INP t_pb_graph_pin *pb_graph_pin) {
574  if(pb_graph_pin->num_output_edges > 1) {
575  return FALSE;
576  }
577  if(pb_graph_pin->num_output_edges == 0) {
578  if(pb_graph_pin->parent_node->pb_type->num_modes == 0) {
579  /* Check that this pin belongs to a primitive */
580  return TRUE;
581  } else {
582  return FALSE;
583  }
584  }
585  return is_forced_connection(pb_graph_pin->output_edges[0]->output_pins[0]);
586 }
587 
588 
589 
590 
static void discover_all_forced_connections(INOUTP t_pb_graph_node *pb_graph_node)
static void sum_pin_class(INOUTP t_pb_graph_node *pb_graph_node)
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
#define INOUTP
Definition: util.h:21
Definition: util.h:12
static int get_max_depth_of_pb_graph_node(INP t_pb_graph_node *pb_graph_node)
static void load_list_of_connectable_input_pin_ptrs(INOUTP t_pb_graph_node *pb_graph_node)
#define INP
Definition: util.h:19
static void load_pin_class_by_depth(INOUTP t_pb_graph_node *pb_graph_node, INP int depth, OUTP int *input_count, OUTP int *output_count)
static void expand_pb_graph_node_and_load_pin_class_by_depth(INOUTP t_pb_graph_pin *current_pb_graph_pin, INP t_pb_graph_pin *reference_pb_graph_pin, INP int depth, OUTP int *input_count, OUTP int *output_count)
static boolean is_forced_connection(INP t_pb_graph_pin *pb_graph_pin)
static void reset_pin_class_scratch_pad_rec(INOUTP t_pb_graph_node *pb_graph_node)
static void alloc_pin_classes_in_pb_graph_node(INOUTP t_pb_graph_node *pb_graph_node)
void load_pin_classes_in_pb_graph_head(INOUTP t_pb_graph_node *pb_graph_node)
static void * my_realloc(void *memblk, int ibytes)
Definition: graphics.c:512
static void expand_pb_graph_node_and_load_output_to_input_connections(INOUTP t_pb_graph_pin *current_pb_graph_pin, INOUTP t_pb_graph_pin *reference_pin, INP int depth)
Definition: slre.c:50
#define OUTP
Definition: util.h:20
messagelogger vpr_printf
Definition: util.c:17
Definition: util.h:12
static void unmark_fanout_intermediate_nodes(INOUTP t_pb_graph_pin *current_pb_graph_pin)