00001 #include <stdio.h>
00002 #include "util.h"
00003 #include "vpr_types.h"
00004 #include "globals.h"
00005 #include "mst.h"
00006 #include "route_export.h"
00007 #include "route_common.h"
00008 #include "route_breadth_first.h"
00009
00010
00011
00012
00013 static boolean breadth_first_route_net(int inet,
00014 float bend_cost);
00015
00016 static void breadth_first_expand_trace_segment(struct s_trace *start_ptr,
00017 int
00018 remaining_connections_to_sink);
00019
00020 static void breadth_first_expand_neighbours(int inode,
00021 float pcost,
00022 int inet,
00023 float bend_cost);
00024
00025 static void breadth_first_add_source_to_heap(int inet);
00026
00027
00028
00029
00030 boolean
00031 try_breadth_first_route(struct s_router_opts router_opts,
00032 t_ivec ** fb_opins_used_locally,
00033 int width_fac)
00034 {
00035
00036
00037
00038
00039
00040 float pres_fac;
00041 boolean success, is_routable, rip_up_local_opins;
00042 int itry, inet;
00043
00044
00045
00046
00047
00048 pres_fac = router_opts.first_iter_pres_fac;
00049
00050 for(itry = 1; itry <= router_opts.max_router_iterations; itry++)
00051 {
00052
00053 for(inet = 0; inet < num_nets; inet++)
00054 {
00055 if(net[inet].is_global == FALSE)
00056 {
00057
00058 pathfinder_update_one_cost(trace_head[inet], -1,
00059 pres_fac);
00060
00061 is_routable =
00062 breadth_first_route_net(inet,
00063 router_opts.
00064 bend_cost);
00065
00066
00067
00068 if(!is_routable)
00069 {
00070 printf("Routing failed.\n");
00071 return (FALSE);
00072 }
00073
00074 pathfinder_update_one_cost(trace_head[inet], 1,
00075 pres_fac);
00076
00077 }
00078 }
00079
00080
00081
00082
00083 if(itry == 1)
00084 rip_up_local_opins = FALSE;
00085 else
00086 rip_up_local_opins = TRUE;
00087
00088 reserve_locally_used_opins(pres_fac, rip_up_local_opins,
00089 fb_opins_used_locally);
00090
00091 success = feasible_routing();
00092 if(success)
00093 {
00094 printf
00095 ("Successfully routed after %d routing iterations.\n",
00096 itry);
00097 return (TRUE);
00098 }
00099
00100 if(itry == 1)
00101 pres_fac = router_opts.initial_pres_fac;
00102 else
00103 pres_fac *= router_opts.pres_fac_mult;
00104
00105 pres_fac = min (pres_fac, HUGE_FLOAT / 1e5);
00106
00107 pathfinder_update_cost(pres_fac, router_opts.acc_fac);
00108 }
00109
00110 printf("Routing failed.\n");
00111 return (FALSE);
00112 }
00113
00114
00115 static boolean
00116 breadth_first_route_net(int inet,
00117 float bend_cost)
00118 {
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 int i, inode, prev_node, remaining_connections_to_sink;
00134 float pcost, new_pcost;
00135 struct s_heap *current;
00136 struct s_trace *tptr;
00137
00138 free_traceback(inet);
00139 breadth_first_add_source_to_heap(inet);
00140 mark_ends(inet);
00141
00142 tptr = NULL;
00143 remaining_connections_to_sink = 0;
00144
00145 for(i = 1; i <= net[inet].num_sinks; i++)
00146 {
00147 breadth_first_expand_trace_segment(tptr,
00148 remaining_connections_to_sink);
00149 current = get_heap_head();
00150
00151 if(current == NULL)
00152 {
00153 reset_path_costs();
00154 return (FALSE);
00155 }
00156
00157 inode = current->index;
00158
00159 while(rr_node_route_inf[inode].target_flag == 0)
00160 {
00161 pcost = rr_node_route_inf[inode].path_cost;
00162 new_pcost = current->cost;
00163 if(pcost > new_pcost)
00164 {
00165 rr_node_route_inf[inode].path_cost = new_pcost;
00166 prev_node = current->u.prev_node;
00167 rr_node_route_inf[inode].prev_node = prev_node;
00168 rr_node_route_inf[inode].prev_edge =
00169 current->prev_edge;
00170
00171 if(pcost > 0.99 * HUGE_FLOAT)
00172 add_to_mod_list(&rr_node_route_inf[inode].
00173 path_cost);
00174
00175 breadth_first_expand_neighbours(inode, new_pcost,
00176 inet, bend_cost);
00177 }
00178
00179 free_heap_data(current);
00180 current = get_heap_head();
00181
00182 if(current == NULL)
00183 {
00184 reset_path_costs();
00185 return (FALSE);
00186 }
00187
00188 inode = current->index;
00189 }
00190
00191 rr_node_route_inf[inode].target_flag--;
00192 remaining_connections_to_sink =
00193 rr_node_route_inf[inode].target_flag;
00194 tptr = update_traceback(current, inet);
00195 free_heap_data(current);
00196 }
00197
00198 empty_heap();
00199 reset_path_costs();
00200 return (TRUE);
00201 }
00202
00203
00204 static void
00205 breadth_first_expand_trace_segment(struct s_trace *start_ptr,
00206 int remaining_connections_to_sink)
00207 {
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 struct s_trace *tptr, *next_ptr;
00226 int inode, sink_node, last_ipin_node;
00227
00228 tptr = start_ptr;
00229
00230 if(remaining_connections_to_sink == 0)
00231 {
00232 while(tptr != NULL)
00233 {
00234 node_to_heap(tptr->index, 0., NO_PREVIOUS, NO_PREVIOUS,
00235 OPEN, OPEN);
00236 tptr = tptr->next;
00237 }
00238 }
00239
00240 else
00241 {
00242
00243
00244
00245
00246
00247
00248
00249 if(tptr == NULL)
00250 return;
00251
00252 next_ptr = tptr->next;
00253 last_ipin_node = OPEN;
00254
00255
00256
00257
00258
00259 while(next_ptr != NULL)
00260 {
00261 inode = tptr->index;
00262 node_to_heap(inode, 0., NO_PREVIOUS, NO_PREVIOUS, OPEN,
00263 OPEN);
00264
00265 if(rr_node[inode].type == IPIN)
00266 last_ipin_node = inode;
00267
00268 tptr = next_ptr;
00269 next_ptr = tptr->next;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278 rr_node_route_inf[last_ipin_node].path_cost = -HUGE_FLOAT;
00279
00280
00281
00282
00283 sink_node = tptr->index;
00284 rr_node_route_inf[sink_node].path_cost = HUGE_FLOAT;
00285
00286
00287
00288
00289
00290 invalidate_heap_entries(sink_node, last_ipin_node);
00291 }
00292 }
00293
00294
00295 static void
00296 breadth_first_expand_neighbours(int inode,
00297 float pcost,
00298 int inet,
00299 float bend_cost)
00300 {
00301
00302
00303
00304
00305
00306 int iconn, to_node, num_edges;
00307 t_rr_type from_type, to_type;
00308 float tot_cost;
00309
00310 num_edges = rr_node[inode].num_edges;
00311 for(iconn = 0; iconn < num_edges; iconn++)
00312 {
00313 to_node = rr_node[inode].edges[iconn];
00314
00315 if(rr_node[to_node].xhigh < route_bb[inet].xmin ||
00316 rr_node[to_node].xlow > route_bb[inet].xmax ||
00317 rr_node[to_node].yhigh < route_bb[inet].ymin ||
00318 rr_node[to_node].ylow > route_bb[inet].ymax)
00319 continue;
00320
00321 tot_cost = pcost + get_rr_cong_cost(to_node);
00322
00323 if(bend_cost != 0.)
00324 {
00325 from_type = rr_node[inode].type;
00326 to_type = rr_node[to_node].type;
00327 if((from_type == CHANX && to_type == CHANY) ||
00328 (from_type == CHANY && to_type == CHANX))
00329 tot_cost += bend_cost;
00330 }
00331
00332 node_to_heap(to_node, tot_cost, inode, iconn, OPEN, OPEN);
00333 }
00334 }
00335
00336
00337 static void
00338 breadth_first_add_source_to_heap(int inet)
00339 {
00340
00341
00342
00343 int inode;
00344 float cost;
00345
00346 inode = net_rr_terminals[inet][0];
00347 cost = get_rr_cong_cost(inode);
00348
00349 node_to_heap(inode, cost, NO_PREVIOUS, NO_PREVIOUS, OPEN, OPEN);
00350 }