00001 #include <stdio.h>
00002 #include "util.h"
00003 #include "vpr_types.h"
00004 #include "globals.h"
00005 #include "route_common.h"
00006 #include "route_tree_timing.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 static t_rt_node **rr_node_to_rt_node = NULL;
00026
00027
00028
00029 static t_rt_node *rt_node_free_list = NULL;
00030 static t_linked_rt_edge *rt_edge_free_list = NULL;
00031
00032
00033
00034
00035
00036 static t_rt_node *alloc_rt_node(void);
00037
00038 static void free_rt_node(t_rt_node * rt_node);
00039
00040 static t_linked_rt_edge *alloc_linked_rt_edge(void);
00041
00042 static void free_linked_rt_edge(t_linked_rt_edge * rt_edge);
00043
00044 static t_rt_node *add_path_to_route_tree(struct s_heap *hptr,
00045 t_rt_node ** sink_rt_node_ptr);
00046
00047 static void load_new_path_R_upstream(t_rt_node * start_of_new_path_rt_node);
00048
00049 static t_rt_node *update_unbuffered_ancestors_C_downstream(t_rt_node
00050 *
00051 start_of_new_path_rt_node);
00052
00053 static void load_rt_subtree_Tdel(t_rt_node * subtree_rt_root,
00054 float Tarrival);
00055
00056
00057
00058
00059
00060 void
00061 alloc_route_tree_timing_structs(void)
00062 {
00063
00064
00065
00066 if(rr_node_to_rt_node != NULL || rt_node_free_list != NULL ||
00067 rt_node_free_list != NULL)
00068 {
00069 printf("Error in alloc_route_tree_timing_structs: old structures "
00070 "already exist.\n");
00071 exit(1);
00072 }
00073
00074 rr_node_to_rt_node = (t_rt_node **) my_malloc(num_rr_nodes *
00075 sizeof(t_rt_node *));
00076 }
00077
00078
00079 void
00080 free_route_tree_timing_structs(void)
00081 {
00082
00083
00084
00085
00086 t_rt_node *rt_node, *next_node;
00087 t_linked_rt_edge *rt_edge, *next_edge;
00088
00089 free(rr_node_to_rt_node);
00090 rr_node_to_rt_node = NULL;
00091
00092 rt_node = rt_node_free_list;
00093
00094 while(rt_node != NULL)
00095 {
00096 next_node = rt_node->u.next;
00097 free(rt_node);
00098 rt_node = next_node;
00099 }
00100
00101 rt_node_free_list = NULL;
00102
00103 rt_edge = rt_edge_free_list;
00104
00105 while(rt_edge != NULL)
00106 {
00107 next_edge = rt_edge->next;
00108 free(rt_edge);
00109 rt_edge = next_edge;
00110 }
00111
00112 rt_edge_free_list = NULL;
00113 }
00114
00115
00116 static t_rt_node *
00117 alloc_rt_node(void)
00118 {
00119
00120
00121
00122
00123 t_rt_node *rt_node;
00124
00125 rt_node = rt_node_free_list;
00126
00127 if(rt_node != NULL)
00128 {
00129 rt_node_free_list = rt_node->u.next;
00130 }
00131 else
00132 {
00133 rt_node = (t_rt_node *) my_malloc(sizeof(t_rt_node));
00134 }
00135
00136 return (rt_node);
00137 }
00138
00139
00140 static void
00141 free_rt_node(t_rt_node * rt_node)
00142 {
00143
00144
00145
00146 rt_node->u.next = rt_node_free_list;
00147 rt_node_free_list = rt_node;
00148 }
00149
00150
00151 static t_linked_rt_edge *
00152 alloc_linked_rt_edge(void)
00153 {
00154
00155
00156
00157
00158 t_linked_rt_edge *linked_rt_edge;
00159
00160 linked_rt_edge = rt_edge_free_list;
00161
00162 if(linked_rt_edge != NULL)
00163 {
00164 rt_edge_free_list = linked_rt_edge->next;
00165 }
00166 else
00167 {
00168 linked_rt_edge = (t_linked_rt_edge *) my_malloc(sizeof
00169 (t_linked_rt_edge));
00170 }
00171
00172 return (linked_rt_edge);
00173 }
00174
00175
00176 static void
00177 free_linked_rt_edge(t_linked_rt_edge * rt_edge)
00178 {
00179
00180
00181
00182 rt_edge->next = rt_edge_free_list;
00183 rt_edge_free_list = rt_edge;
00184 }
00185
00186
00187 t_rt_node *
00188 init_route_tree_to_source(int inet)
00189 {
00190
00191
00192
00193
00194 t_rt_node *rt_root;
00195 int inode;
00196
00197 rt_root = alloc_rt_node();
00198 rt_root->u.child_list = NULL;
00199 rt_root->parent_node = NULL;
00200 rt_root->parent_switch = OPEN;
00201 rt_root->re_expand = TRUE;
00202
00203 inode = net_rr_terminals[inet][0];
00204
00205 rt_root->inode = inode;
00206 rt_root->C_downstream = rr_node[inode].C;
00207 rt_root->R_upstream = rr_node[inode].R;
00208 rt_root->Tdel = 0.5 * rr_node[inode].R * rr_node[inode].C;
00209 rr_node_to_rt_node[inode] = rt_root;
00210
00211 return (rt_root);
00212 }
00213
00214
00215 t_rt_node *
00216 update_route_tree(struct s_heap * hptr)
00217 {
00218
00219
00220
00221
00222
00223
00224 t_rt_node *start_of_new_path_rt_node, *sink_rt_node;
00225 t_rt_node *unbuffered_subtree_rt_root, *subtree_parent_rt_node;
00226 float Tdel_start;
00227 short iswitch;
00228
00229 start_of_new_path_rt_node = add_path_to_route_tree(hptr, &sink_rt_node);
00230 load_new_path_R_upstream(start_of_new_path_rt_node);
00231 unbuffered_subtree_rt_root =
00232 update_unbuffered_ancestors_C_downstream(start_of_new_path_rt_node);
00233
00234 subtree_parent_rt_node = unbuffered_subtree_rt_root->parent_node;
00235
00236 if(subtree_parent_rt_node != NULL)
00237 {
00238 Tdel_start = subtree_parent_rt_node->Tdel;
00239 iswitch = unbuffered_subtree_rt_root->parent_switch;
00240 Tdel_start += switch_inf[iswitch].R *
00241 unbuffered_subtree_rt_root->C_downstream;
00242 Tdel_start += switch_inf[iswitch].Tdel;
00243 }
00244 else
00245 {
00246 Tdel_start = 0.;
00247 }
00248
00249 load_rt_subtree_Tdel(unbuffered_subtree_rt_root, Tdel_start);
00250
00251 return (sink_rt_node);
00252 }
00253
00254
00255 static t_rt_node *
00256 add_path_to_route_tree(struct s_heap *hptr,
00257 t_rt_node ** sink_rt_node_ptr)
00258 {
00259
00260
00261
00262
00263
00264 int inode, remaining_connections_to_sink;
00265 short iedge, iswitch;
00266 float C_downstream;
00267 t_rt_node *rt_node, *downstream_rt_node, *sink_rt_node;
00268 t_linked_rt_edge *linked_rt_edge;
00269
00270
00271 inode = hptr->index;
00272
00273 #ifdef DEBUG
00274 if(rr_node[inode].type != SINK)
00275 {
00276 printf
00277 ("Error in add_path_to_route_tree. Expected type = SINK (%d).\n",
00278 SINK);
00279 printf("Got type = %d.", rr_node[inode].type);
00280 exit(1);
00281 }
00282 #endif
00283
00284 remaining_connections_to_sink = rr_node_route_inf[inode].target_flag;
00285 sink_rt_node = alloc_rt_node();
00286 sink_rt_node->u.child_list = NULL;
00287 sink_rt_node->inode = inode;
00288 C_downstream = rr_node[inode].C;
00289 sink_rt_node->C_downstream = C_downstream;
00290 rr_node_to_rt_node[inode] = sink_rt_node;
00291
00292
00293
00294
00295
00296
00297 #define NO_ROUTE_THROUGHS 1
00298
00299 #ifdef NO_ROUTE_THROUGHS
00300 sink_rt_node->re_expand = FALSE;
00301 #else
00302 if(remaining_connections_to_sink == 0)
00303 {
00304 sink_rt_node->re_expand = TRUE;
00305 }
00306
00307
00308
00309
00310
00311 else
00312 {
00313 sink_rt_node->re_expand = FALSE;
00314 }
00315 #endif
00316
00317
00318
00319
00320 downstream_rt_node = sink_rt_node;
00321 inode = hptr->u.prev_node;
00322 iedge = hptr->prev_edge;
00323 iswitch = rr_node[inode].switches[iedge];
00324
00325
00326
00327 while(rr_node_route_inf[inode].prev_node != NO_PREVIOUS)
00328 {
00329 linked_rt_edge = alloc_linked_rt_edge();
00330 linked_rt_edge->child = downstream_rt_node;
00331 linked_rt_edge->iswitch = iswitch;
00332 linked_rt_edge->next = NULL;
00333
00334 rt_node = alloc_rt_node();
00335 downstream_rt_node->parent_node = rt_node;
00336 downstream_rt_node->parent_switch = iswitch;
00337
00338 rt_node->u.child_list = linked_rt_edge;
00339 rt_node->inode = inode;
00340
00341 if(switch_inf[iswitch].buffered == FALSE)
00342 C_downstream += rr_node[inode].C;
00343 else
00344 C_downstream = rr_node[inode].C;
00345
00346 rt_node->C_downstream = C_downstream;
00347 rr_node_to_rt_node[inode] = rt_node;
00348
00349 #ifdef NO_ROUTE_THROUGHS
00350 if(rr_node[inode].type == IPIN)
00351 rt_node->re_expand = FALSE;
00352 else
00353 rt_node->re_expand = TRUE;
00354
00355 #else
00356 if(remaining_connections_to_sink == 0)
00357 {
00358 rt_node->re_expand = TRUE;
00359 }
00360 else
00361 {
00362 rt_node->re_expand = FALSE;
00363
00364
00365
00366 remaining_connections_to_sink = 0;
00367 }
00368 #endif
00369
00370 downstream_rt_node = rt_node;
00371 iedge = rr_node_route_inf[inode].prev_edge;
00372 inode = rr_node_route_inf[inode].prev_node;
00373 iswitch = rr_node[inode].switches[iedge];
00374 }
00375
00376
00377
00378 rt_node = rr_node_to_rt_node[inode];
00379
00380 linked_rt_edge = alloc_linked_rt_edge();
00381 linked_rt_edge->child = downstream_rt_node;
00382 linked_rt_edge->iswitch = iswitch;
00383 linked_rt_edge->next = rt_node->u.child_list;
00384 rt_node->u.child_list = linked_rt_edge;
00385
00386 downstream_rt_node->parent_node = rt_node;
00387 downstream_rt_node->parent_switch = iswitch;
00388
00389 *sink_rt_node_ptr = sink_rt_node;
00390 return (downstream_rt_node);
00391 }
00392
00393
00394 static void
00395 load_new_path_R_upstream(t_rt_node * start_of_new_path_rt_node)
00396 {
00397
00398
00399
00400
00401 float R_upstream;
00402 int inode;
00403 short iswitch;
00404 t_rt_node *rt_node, *parent_rt_node;
00405 t_linked_rt_edge *linked_rt_edge;
00406
00407 rt_node = start_of_new_path_rt_node;
00408 iswitch = rt_node->parent_switch;
00409 inode = rt_node->inode;
00410 parent_rt_node = rt_node->parent_node;
00411
00412 R_upstream = switch_inf[iswitch].R + rr_node[inode].R;
00413
00414 if(switch_inf[iswitch].buffered == FALSE)
00415 R_upstream += parent_rt_node->R_upstream;
00416
00417 rt_node->R_upstream = R_upstream;
00418
00419
00420
00421
00422
00423 linked_rt_edge = rt_node->u.child_list;
00424
00425 while(linked_rt_edge != NULL)
00426 {
00427
00428 #ifdef DEBUG
00429 if(linked_rt_edge->next != NULL)
00430 {
00431 printf
00432 ("Error in load_new_path_R_upstream: new routing addition is\n"
00433 "a tree (not a path).\n");
00434 exit(1);
00435 }
00436 #endif
00437
00438 rt_node = linked_rt_edge->child;
00439 iswitch = linked_rt_edge->iswitch;
00440 inode = rt_node->inode;
00441
00442 if(switch_inf[iswitch].buffered)
00443 R_upstream = switch_inf[iswitch].R + rr_node[inode].R;
00444 else
00445 R_upstream += switch_inf[iswitch].R + rr_node[inode].R;
00446
00447 rt_node->R_upstream = R_upstream;
00448 linked_rt_edge = rt_node->u.child_list;
00449 }
00450 }
00451
00452
00453 static t_rt_node *
00454 update_unbuffered_ancestors_C_downstream(t_rt_node
00455 * start_of_new_path_rt_node)
00456 {
00457
00458
00459
00460
00461
00462
00463 t_rt_node *rt_node, *parent_rt_node;
00464 short iswitch;
00465 float C_downstream_addition;
00466
00467 rt_node = start_of_new_path_rt_node;
00468 C_downstream_addition = rt_node->C_downstream;
00469 parent_rt_node = rt_node->parent_node;
00470 iswitch = rt_node->parent_switch;
00471
00472 while(parent_rt_node != NULL && switch_inf[iswitch].buffered == FALSE)
00473 {
00474 rt_node = parent_rt_node;
00475 rt_node->C_downstream += C_downstream_addition;
00476 parent_rt_node = rt_node->parent_node;
00477 iswitch = rt_node->parent_switch;
00478 }
00479
00480 return (rt_node);
00481 }
00482
00483
00484 static void
00485 load_rt_subtree_Tdel(t_rt_node * subtree_rt_root,
00486 float Tarrival)
00487 {
00488
00489
00490
00491
00492
00493
00494 int inode;
00495 short iswitch;
00496 t_rt_node *child_node;
00497 t_linked_rt_edge *linked_rt_edge;
00498 float Tdel, Tchild;
00499
00500 inode = subtree_rt_root->inode;
00501
00502
00503
00504
00505
00506 Tdel = Tarrival + 0.5 * subtree_rt_root->C_downstream * rr_node[inode].R;
00507 subtree_rt_root->Tdel = Tdel;
00508
00509
00510
00511
00512 linked_rt_edge = subtree_rt_root->u.child_list;
00513
00514 while(linked_rt_edge != NULL)
00515 {
00516 iswitch = linked_rt_edge->iswitch;
00517 child_node = linked_rt_edge->child;
00518
00519 Tchild = Tdel + switch_inf[iswitch].R * child_node->C_downstream;
00520 Tchild += switch_inf[iswitch].Tdel;
00521 load_rt_subtree_Tdel(child_node, Tchild);
00522
00523 linked_rt_edge = linked_rt_edge->next;
00524 }
00525 }
00526
00527
00528 void
00529 free_route_tree(t_rt_node * rt_node)
00530 {
00531
00532
00533
00534
00535 t_rt_node *child_node;
00536 t_linked_rt_edge *rt_edge, *next_edge;
00537
00538 rt_edge = rt_node->u.child_list;
00539
00540 while(rt_edge != NULL)
00541 {
00542 child_node = rt_edge->child;
00543 free_route_tree(child_node);
00544 next_edge = rt_edge->next;
00545 free_linked_rt_edge(rt_edge);
00546 rt_edge = next_edge;
00547 }
00548
00549 free_rt_node(rt_node);
00550 }
00551
00552
00553 void
00554 update_net_delays_from_route_tree(float *net_delay,
00555 t_rt_node ** rt_node_of_sink,
00556 int inet)
00557 {
00558
00559
00560
00561
00562 int isink;
00563 t_rt_node *sink_rt_node;
00564
00565 for(isink = 1; isink <= net[inet].num_sinks; isink++)
00566 {
00567 sink_rt_node = rt_node_of_sink[isink];
00568 net_delay[isink] = sink_rt_node->Tdel;
00569 }
00570 }