VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
route_export.h File Reference
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

boolean try_route (int width_fac, struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf, float **net_delay, t_slack *slacks, t_chan_width_dist chan_width_dist, t_ivec **clb_opins_used_locally, boolean *Fc_clipped, t_direct_inf *directs, int num_directs)
 
boolean feasible_routing (void)
 
t_ivec ** alloc_route_structs (void)
 
void free_route_structs ()
 
struct s_trace ** alloc_saved_routing (t_ivec **clb_opins_used_locally, t_ivec ***saved_clb_opins_used_locally_ptr)
 
void free_saved_routing (struct s_trace **best_routing, t_ivec **saved_clb_opins_used_locally)
 
void save_routing (struct s_trace **best_routing, t_ivec **clb_opins_used_locally, t_ivec **saved_clb_opins_used_locally)
 
void restore_routing (struct s_trace **best_routing, t_ivec **clb_opins_used_locally, t_ivec **saved_clb_opins_used_locally)
 
void get_serial_num (void)
 
void print_route (char *name)
 

Function Documentation

t_ivec** alloc_route_structs ( void  )

Definition at line 611 of file route_common.c.

611  {
612 
613  /* Allocates the data structures needed for routing. */
614 
616 
618  clb_opins_used_locally = alloc_and_load_clb_opins_used_locally();
619 
620  return (clb_opins_used_locally);
621 }
static t_ivec ** clb_opins_used_locally
void alloc_route_static_structs(void)
Definition: route_common.c:623
Definition: util.h:47
static t_ivec ** alloc_and_load_clb_opins_used_locally(void)
Definition: route_common.c:679

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

struct s_trace** alloc_saved_routing ( t_ivec **  clb_opins_used_locally,
t_ivec ***  saved_clb_opins_used_locally_ptr 
)

Definition at line 638 of file route_common.c.

639  {
640 
641  /* Allocates data structures into which the key routing data can be saved, *
642  * allowing the routing to be recovered later (e.g. after a another routing *
643  * is attempted). */
644 
645  struct s_trace **best_routing;
646  t_ivec **saved_clb_opins_used_locally;
647  int iblk, iclass, num_local_opins;
648  t_type_ptr type;
649 
650  best_routing = (struct s_trace **) my_calloc(num_nets,
651  sizeof(struct s_trace *));
652 
653  saved_clb_opins_used_locally = (t_ivec **) my_malloc(
654  num_blocks * sizeof(t_ivec *));
655 
656  for (iblk = 0; iblk < num_blocks; iblk++) {
657  type = block[iblk].type;
658  saved_clb_opins_used_locally[iblk] = (t_ivec *) my_malloc(
659  type->num_class * sizeof(t_ivec));
660  for (iclass = 0; iclass < type->num_class; iclass++) {
661  num_local_opins = clb_opins_used_locally[iblk][iclass].nelem;
662  saved_clb_opins_used_locally[iblk][iclass].nelem = num_local_opins;
663 
664  if (num_local_opins == 0) {
665  saved_clb_opins_used_locally[iblk][iclass].list = NULL;
666  } else {
667  saved_clb_opins_used_locally[iblk][iclass].list =
668  (int *) my_malloc(num_local_opins * sizeof(int));
669  }
670  }
671  }
672 
673  *saved_clb_opins_used_locally_ptr = saved_clb_opins_used_locally;
674  return (best_routing);
675 }
int * list
Definition: util.h:49
void * my_calloc(size_t nelem, size_t size)
Definition: util.c:132
int num_nets
Definition: globals.c:27
t_type_ptr type
Definition: vpr_types.h:561
int num_blocks
Definition: globals.c:30
static void * my_malloc(int ibytes)
Definition: graphics.c:499
struct s_block * block
Definition: globals.c:31
int nelem
Definition: util.h:48
Definition: util.h:47
static struct s_trace ** best_routing

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

boolean feasible_routing ( void  )

Definition at line 298 of file route_common.c.

298  {
299 
300  /* This routine checks to see if this is a resource-feasible routing. *
301  * That is, are all rr_node capacity limitations respected? It assumes *
302  * that the occupancy arrays are up to date when it is called. */
303 
304  int inode;
305 
306  for (inode = 0; inode < num_rr_nodes; inode++) {
307  if (rr_node[inode].occ > rr_node[inode].capacity) {
308  return (FALSE);
309  }
310  }
311 
312  return (TRUE);
313 }
t_rr_node * rr_node
Definition: globals.c:70
Definition: util.h:12
int num_rr_nodes
Definition: globals.c:69
Definition: util.h:12

+ Here is the caller graph for this function:

void free_route_structs ( )

Definition at line 750 of file route_common.c.

750  {
751 
752  /* Frees the temporary storage needed only during the routing. The *
753  * final routing result is not freed. */
754  if(heap != NULL) {
755  free(heap + 1);
756  }
757  if(route_bb != NULL) {
758  free(route_bb);
759  }
760 
761  heap = NULL; /* Defensive coding: crash hard if I use these. */
762  route_bb = NULL;
763 
764  /*free the memory chunks that were used by heap and linked f pointer */
767  heap_free_head = NULL;
769 }
static t_chunk heap_ch
Definition: route_common.c:36
static struct s_heap ** heap
Definition: route_common.c:29
static struct s_linked_f_pointer * linked_f_pointer_free_head
Definition: route_common.c:50
static struct s_heap * heap_free_head
Definition: route_common.c:34
static t_chunk linked_f_pointer_ch
Definition: route_common.c:52
struct s_bb * route_bb
Definition: route_common.c:23
void free_chunk_memory(t_chunk *chunk_info)
Definition: util.c:270

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void free_saved_routing ( struct s_trace **  best_routing,
t_ivec **  saved_clb_opins_used_locally 
)

Definition at line 771 of file route_common.c.

772  {
773 
774  /* Frees the data structures needed to save a routing. */
775  int i;
776 
777  free(best_routing);
778  for (i = 0; i < num_blocks; i++) {
779  free_ivec_vector(saved_clb_opins_used_locally[i], 0,
780  block[i].type->num_class - 1);
781  }
782  free(saved_clb_opins_used_locally);
783 }
int num_blocks
Definition: globals.c:30
struct s_block * block
Definition: globals.c:31
void free_ivec_vector(struct s_ivec *ivec_vector, int nrmin, int nrmax)
Definition: util.c:498

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void get_serial_num ( void  )

Definition at line 188 of file route_common.c.

188  {
189 
190  /* This routine finds a "magic cookie" for the routing and prints it. *
191  * Use this number as a routing serial number to ensure that programming *
192  * changes do not break the router. */
193 
194  int inet, serial_num, inode;
195  struct s_trace *tptr;
196 
197  serial_num = 0;
198 
199  for (inet = 0; inet < num_nets; inet++) {
200 
201  /* Global nets will have null trace_heads (never routed) so they *
202  * are not included in the serial number calculation. */
203 
204  tptr = trace_head[inet];
205  while (tptr != NULL) {
206  inode = tptr->index;
207  serial_num += (inet + 1)
208  * (rr_node[inode].xlow * (nx + 1) - rr_node[inode].yhigh);
209 
210  serial_num -= rr_node[inode].ptc_num * (inet + 1) * 10;
211 
212  serial_num -= rr_node[inode].type * (inet + 1) * 100;
213  serial_num %= 2000000000; /* Prevent overflow */
214  tptr = tptr->next;
215  }
216  }
217  vpr_printf(TIO_MESSAGE_INFO, "Serial number (magic cookie) for the routing is: %d\n", serial_num);
218 }
int index
Definition: vpr_types.h:866
t_rr_node * rr_node
Definition: globals.c:70
short ptc_num
Definition: vpr_types.h:895
int num_nets
Definition: globals.c:27
struct s_trace * next
Definition: vpr_types.h:870
int nx
Definition: globals.c:46
struct s_trace ** trace_head
Definition: globals.c:64
short yhigh
Definition: vpr_types.h:893
messagelogger vpr_printf
Definition: util.c:17
t_rr_type type
Definition: vpr_types.h:902

+ Here is the caller graph for this function:

void print_route ( char *  name)

Definition at line 1095 of file route_common.c.

1095  {
1096 
1097  /* Prints out the routing to file route_file. */
1098 
1099  int inet, inode, ipin, bnum, ilow, jlow, node_block_pin, iclass;
1100  t_rr_type rr_type;
1101  struct s_trace *tptr;
1102  const char *name_type[] = { "SOURCE", "SINK", "IPIN", "OPIN", "CHANX", "CHANY",
1103  "INTRA_CLUSTER_EDGE" };
1104  FILE *fp;
1105 
1106  fp = fopen(route_file, "w");
1107 
1108  fprintf(fp, "Array size: %d x %d logic blocks.\n", nx, ny);
1109  fprintf(fp, "\nRouting:");
1110  for (inet = 0; inet < num_nets; inet++) {
1111  if (clb_net[inet].is_global == FALSE) {
1112  if (clb_net[inet].num_sinks == FALSE) {
1113  fprintf(fp, "\n\nNet %d (%s)\n\n", inet, clb_net[inet].name);
1114  fprintf(fp, "\n\nUsed in local cluster only, reserved one CLB pin\n\n");
1115  } else {
1116  fprintf(fp, "\n\nNet %d (%s)\n\n", inet, clb_net[inet].name);
1117  tptr = trace_head[inet];
1118 
1119  while (tptr != NULL) {
1120  inode = tptr->index;
1121  rr_type = rr_node[inode].type;
1122  ilow = rr_node[inode].xlow;
1123  jlow = rr_node[inode].ylow;
1124 
1125  fprintf(fp, "Node:\t%d\t%6s (%d,%d) ", inode, name_type[rr_type], ilow, jlow);
1126 
1127  if ((ilow != rr_node[inode].xhigh)
1128  || (jlow != rr_node[inode].yhigh))
1129  fprintf(fp, "to (%d,%d) ", rr_node[inode].xhigh,
1130  rr_node[inode].yhigh);
1131 
1132  switch (rr_type) {
1133 
1134  case IPIN:
1135  case OPIN:
1136  if (grid[ilow][jlow].type == IO_TYPE) {
1137  fprintf(fp, " Pad: ");
1138  } else { /* IO Pad. */
1139  fprintf(fp, " Pin: ");
1140  }
1141  break;
1142 
1143  case CHANX:
1144  case CHANY:
1145  fprintf(fp, " Track: ");
1146  break;
1147 
1148  case SOURCE:
1149  case SINK:
1150  if (grid[ilow][jlow].type == IO_TYPE) {
1151  fprintf(fp, " Pad: ");
1152  } else { /* IO Pad. */
1153  fprintf(fp, " Class: ");
1154  }
1155  break;
1156 
1157  default:
1158  vpr_printf(TIO_MESSAGE_ERROR, "in print_route: Unexpected traceback element type: %d (%s).\n",
1159  rr_type, name_type[rr_type]);
1160  exit(1);
1161  break;
1162  }
1163 
1164  fprintf(fp, "%d ", rr_node[inode].ptc_num);
1165 
1166  /* Uncomment line below if you're debugging and want to see the switch types *
1167  * used in the routing. */
1168  /* fprintf (fp, "Switch: %d", tptr->iswitch); */
1169 
1170  fprintf(fp, "\n");
1171 
1172  tptr = tptr->next;
1173  }
1174  }
1175  }
1176 
1177  else { /* Global net. Never routed. */
1178  fprintf(fp, "\n\nNet %d (%s): global net connecting:\n\n", inet,
1179  clb_net[inet].name);
1180 
1181  for (ipin = 0; ipin <= clb_net[inet].num_sinks; ipin++) {
1182  bnum = clb_net[inet].node_block[ipin];
1183 
1184  node_block_pin = clb_net[inet].node_block_pin[ipin];
1185  iclass = block[bnum].type->pin_class[node_block_pin];
1186 
1187  fprintf(fp, "Block %s (#%d) at (%d, %d), Pin class %d.\n",
1188  block[bnum].name, bnum, block[bnum].x, block[bnum].y,
1189  iclass);
1190  }
1191  }
1192  }
1193 
1194  fclose(fp);
1195 
1197  fp = my_fopen(getEchoFileName(E_ECHO_MEM), "w", 0);
1198  fprintf(fp, "\nNum_heap_allocated: %d Num_trace_allocated: %d\n",
1199  num_heap_allocated, num_trace_allocated);
1200  fprintf(fp, "Num_linked_f_pointer_allocated: %d\n",
1201  num_linked_f_pointer_allocated);
1202  fclose(fp);
1203  }
1204 
1205 }
int * node_block_pin
Definition: vpr_types.h:509
int index
Definition: vpr_types.h:866
FILE * my_fopen(const char *fname, const char *flag, int prompt)
Definition: util.c:54
t_rr_node * rr_node
Definition: globals.c:70
short ylow
Definition: vpr_types.h:892
int num_nets
Definition: globals.c:27
int * node_block
Definition: vpr_types.h:507
t_type_ptr type
Definition: vpr_types.h:561
boolean getEchoEnabled(void)
Definition: ReadOptions.c:67
static const char * name_type[]
Definition: draw.c:87
Definition: util.h:12
struct s_trace * next
Definition: vpr_types.h:870
boolean * is_global
struct s_block * block
Definition: globals.c:31
struct s_net * clb_net
Definition: globals.c:28
int nx
Definition: globals.c:46
struct s_trace ** trace_head
Definition: globals.c:64
boolean isEchoFileEnabled(enum e_echo_files echo_option)
Definition: ReadOptions.c:115
struct s_grid_tile ** grid
Definition: globals.c:59
enum e_rr_type t_rr_type
t_type_ptr IO_TYPE
Definition: globals.c:40
short xlow
Definition: vpr_types.h:890
char * getEchoFileName(enum e_echo_files echo_option)
Definition: ReadOptions.c:122
int ny
Definition: globals.c:47
messagelogger vpr_printf
Definition: util.c:17
int num_sinks
Definition: vpr_types.h:506
t_rr_type type
Definition: vpr_types.h:902

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void restore_routing ( struct s_trace **  best_routing,
t_ivec **  clb_opins_used_locally,
t_ivec **  saved_clb_opins_used_locally 
)

Definition at line 149 of file route_common.c.

151  {
152 
153  /* Deallocates any current routing in trace_head, and replaces it with *
154  * the routing in best_routing. Best_routing is set to NULL to show that *
155  * it no longer points to a valid routing. NOTE: trace_tail is not *
156  * restored -- it is set to all NULLs since it is only used in *
157  * update_traceback. If you need trace_tail restored, modify this *
158  * routine. Also restores the locally used opin data. */
159 
160  int inet, iblk, ipin, iclass, num_local_opins;
161  t_type_ptr type;
162 
163  for (inet = 0; inet < num_nets; inet++) {
164 
165  /* Free any current routing. */
166  free_traceback(inet);
167 
168  /* Set the current routing to the saved one. */
169  trace_head[inet] = best_routing[inet];
170  best_routing[inet] = NULL; /* No stored routing. */
171  }
172 
173  /* Save which OPINs are locally used. */
174 
175  for (iblk = 0; iblk < num_blocks; iblk++) {
176  type = block[iblk].type;
177  for (iclass = 0; iclass < type->num_class; iclass++) {
178  num_local_opins = clb_opins_used_locally[iblk][iclass].nelem;
179  for (ipin = 0; ipin < num_local_opins; ipin++) {
180  clb_opins_used_locally[iblk][iclass].list[ipin] =
181  saved_clb_opins_used_locally[iblk][iclass].list[ipin];
182  }
183  }
184 
185  }
186 }
void free_traceback(int inet)
Definition: route_common.c:587
int * list
Definition: util.h:49
int num_nets
Definition: globals.c:27
t_type_ptr type
Definition: vpr_types.h:561
int num_blocks
Definition: globals.c:30
struct s_block * block
Definition: globals.c:31
int nelem
Definition: util.h:48
struct s_trace ** trace_head
Definition: globals.c:64

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void save_routing ( struct s_trace **  best_routing,
t_ivec **  clb_opins_used_locally,
t_ivec **  saved_clb_opins_used_locally 
)

Definition at line 99 of file route_common.c.

101  {
102 
103  /* This routing frees any routing currently held in best routing, *
104  * then copies over the current routing (held in trace_head), and *
105  * finally sets trace_head and trace_tail to all NULLs so that the *
106  * connection to the saved routing is broken. This is necessary so *
107  * that the next iteration of the router does not free the saved *
108  * routing elements. Also saves any data about locally used clb_opins, *
109  * since this is also part of the routing. */
110 
111  int inet, iblk, iclass, ipin, num_local_opins;
112  struct s_trace *tptr, *tempptr;
113  t_type_ptr type;
114 
115  for (inet = 0; inet < num_nets; inet++) {
116 
117  /* Free any previously saved routing. It is no longer best. */
118  tptr = best_routing[inet];
119  while (tptr != NULL) {
120  tempptr = tptr->next;
121  free_trace_data(tptr);
122  tptr = tempptr;
123  }
124 
125  /* Save a pointer to the current routing in best_routing. */
126  best_routing[inet] = trace_head[inet];
127 
128  /* Set the current (working) routing to NULL so the current trace *
129  * elements won't be reused by the memory allocator. */
130 
131  trace_head[inet] = NULL;
132  trace_tail[inet] = NULL;
133  }
134 
135  /* Save which OPINs are locally used. */
136 
137  for (iblk = 0; iblk < num_blocks; iblk++) {
138  type = block[iblk].type;
139  for (iclass = 0; iclass < type->num_class; iclass++) {
140  num_local_opins = clb_opins_used_locally[iblk][iclass].nelem;
141  for (ipin = 0; ipin < num_local_opins; ipin++) {
142  saved_clb_opins_used_locally[iblk][iclass].list[ipin] =
143  clb_opins_used_locally[iblk][iclass].list[ipin];
144  }
145  }
146  }
147 }
static void free_trace_data(struct s_trace *tptr)
struct s_trace ** trace_tail
Definition: globals.c:65
int * list
Definition: util.h:49
int num_nets
Definition: globals.c:27
t_type_ptr type
Definition: vpr_types.h:561
int num_blocks
Definition: globals.c:30
struct s_trace * next
Definition: vpr_types.h:870
struct s_block * block
Definition: globals.c:31
int nelem
Definition: util.h:48
struct s_trace ** trace_head
Definition: globals.c:64

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

boolean try_route ( int  width_fac,
struct s_router_opts  router_opts,
struct s_det_routing_arch  det_routing_arch,
t_segment_inf segment_inf,
t_timing_inf  timing_inf,
float **  net_delay,
t_slack slacks,
t_chan_width_dist  chan_width_dist,
t_ivec **  clb_opins_used_locally,
boolean Fc_clipped,
t_direct_inf directs,
int  num_directs 
)

Definition at line 220 of file route_common.c.

224  {
225 
226  /* Attempts a routing via an iterated maze router algorithm. Width_fac *
227  * specifies the relative width of the channels, while the members of *
228  * router_opts determine the value of the costs assigned to routing *
229  * resource node, etc. det_routing_arch describes the detailed routing *
230  * architecture (connection and switch boxes) of the FPGA; it is used *
231  * only if a DETAILED routing has been selected. */
232 
233  int tmp;
234  clock_t begin, end;
235  boolean success;
236  t_graph_type graph_type;
237 
238  if (router_opts.route_type == GLOBAL) {
239  graph_type = GRAPH_GLOBAL;
240  } else {
241  graph_type = (
242  det_routing_arch.directionality == BI_DIRECTIONAL ?
244  }
245 
246  /* Set the channel widths */
247 
248  init_chan(width_fac, chan_width_dist);
249 
250  /* Free any old routing graph, if one exists. */
251 
252  free_rr_graph();
253 
254  begin = clock();
255 
256  /* Set up the routing resource graph defined by this FPGA architecture. */
257 
259  chan_width_x[0], NULL, det_routing_arch.switch_block_type,
260  det_routing_arch.Fs, det_routing_arch.num_segment,
261  det_routing_arch.num_switch, segment_inf,
262  det_routing_arch.global_route_switch,
263  det_routing_arch.delayless_switch, timing_inf,
264  det_routing_arch.wire_to_ipin_switch, router_opts.base_cost_type,
265  directs, num_directs, FALSE,
266  &tmp);
267 
268  end = clock();
269 #ifdef CLOCKS_PER_SEC
270  vpr_printf(TIO_MESSAGE_INFO, "Build rr_graph took %g seconds.\n", (float)(end - begin) / CLOCKS_PER_SEC);
271 #else
272  vpr_printf(TIO_MESSAGE_INFO, "Build rr_graph took %g seconds.\n", (float)(end - begin) / CLK_PER_SEC);
273 #endif
274 
275  /* Allocate and load some additional rr_graph information needed only by *
276  * the router. */
277 
279 
280  init_route_structs(router_opts.bb_factor);
281 
282  if (router_opts.router_algorithm == BREADTH_FIRST) {
283  vpr_printf(TIO_MESSAGE_INFO, "Confirming Router Algorithm: BREADTH_FIRST.\n");
284  success = try_breadth_first_route(router_opts, clb_opins_used_locally,
285  width_fac);
286  } else { /* TIMING_DRIVEN route */
287  vpr_printf(TIO_MESSAGE_INFO, "Confirming Router Algorithm: TIMING_DRIVEN.\n");
288  assert(router_opts.route_type != GLOBAL);
289  success = try_timing_driven_route(router_opts, net_delay, slacks,
290  clb_opins_used_locally,timing_inf.timing_analysis_enabled);
291  }
292 
294 
295  return (success);
296 }
enum e_router_algorithm router_algorithm
Definition: vpr_types.h:705
void free_rr_graph(void)
Definition: rr_graph.c:798
short delayless_switch
Definition: vpr_types.h:764
short global_route_switch
Definition: vpr_types.h:763
static float ** net_delay
enum e_graph_type t_graph_type
Definition: rr_graph.h:11
int * chan_width_x
Definition: globals.c:56
boolean timing_analysis_enabled
boolean try_breadth_first_route(struct s_router_opts router_opts, t_ivec **clb_opins_used_locally, int width_fac)
Definition: util.h:12
void alloc_and_load_rr_node_route_structs(void)
Definition: route_common.c:785
void init_route_structs(int bb_factor)
Definition: route_common.c:394
enum e_directionality directionality
Definition: vpr_types.h:758
void build_rr_graph(INP t_graph_type graph_type, INP int L_num_types, INP t_type_ptr types, INP int L_nx, INP int L_ny, INP struct s_grid_tile **L_grid, INP int chan_width, INP struct s_chan_width_dist *chan_capacity_inf, INP enum e_switch_block_type sb_type, INP int Fs, INP int num_seg_types, INP int num_switches, INP t_segment_inf *segment_inf, INP int global_route_switch, INP int delayless_switch, INP t_timing_inf timing_inf, INP int wire_to_ipin_switch, INP enum e_base_cost_type base_cost_type, INP t_direct_inf *directs, INP int num_directs, INP boolean ignore_Fc_0, OUTP int *Warnings)
Definition: rr_graph.c:192
int nx
Definition: globals.c:46
void init_chan(int cfactor, t_chan_width_dist chan_width_dist)
enum e_route_type route_type
Definition: vpr_types.h:703
struct s_grid_tile ** grid
Definition: globals.c:59
enum e_switch_block_type switch_block_type
Definition: vpr_types.h:760
int num_types
Definition: globals.c:37
void free_rr_node_route_structs(void)
Definition: route_common.c:828
struct s_type_descriptor * type_descriptors
Definition: globals.c:38
int ny
Definition: globals.c:47
messagelogger vpr_printf
Definition: util.c:17
short wire_to_ipin_switch
Definition: vpr_types.h:765
boolean try_timing_driven_route(struct s_router_opts router_opts, float **net_delay, t_slack *slacks, t_ivec **clb_opins_used_locally, boolean timing_analysis_enabled)
Definition: route_timing.c:44
enum e_base_cost_type base_cost_type
Definition: vpr_types.h:706

+ Here is the call graph for this function:

+ Here is the caller graph for this function: