00001 #include <stdio.h>
00002 #include "util.h"
00003 #include "vpr_types.h"
00004 #include "globals.h"
00005 #include "net_delay.h"
00006
00007
00008
00009
00010 struct s_linked_rc_edge
00011 {
00012 struct s_rc_node *child;
00013 short iswitch;
00014 struct s_linked_rc_edge *next;
00015 };
00016
00017 typedef struct s_linked_rc_edge t_linked_rc_edge;
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 struct s_rc_node
00028 {
00029 union
00030 {
00031 t_linked_rc_edge *child_list;
00032 struct s_rc_node *next;
00033 }
00034 u;
00035 int inode;
00036 float C_downstream;
00037 float Tdel;
00038 };
00039
00040 typedef struct s_rc_node t_rc_node;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 struct s_linked_rc_ptr
00056 {
00057 struct s_rc_node *rc_node;
00058 struct s_linked_rc_ptr *next;
00059 };
00060
00061 typedef struct s_linked_rc_ptr t_linked_rc_ptr;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 static t_rc_node *alloc_and_load_rc_tree(int inet,
00072 t_rc_node ** rc_node_free_list_ptr,
00073 t_linked_rc_edge **
00074 rc_edge_free_list_ptr,
00075 t_linked_rc_ptr *
00076 rr_node_to_rc_node);
00077
00078 static void add_to_rc_tree(t_rc_node * parent_rc,
00079 t_rc_node * child_rc,
00080 short iswitch,
00081 int inode,
00082 t_linked_rc_edge ** rc_edge_free_list_ptr);
00083
00084 static t_rc_node *alloc_rc_node(t_rc_node ** rc_node_free_list_ptr);
00085
00086 static void free_rc_node(t_rc_node * rc_node,
00087 t_rc_node ** rc_node_free_list_ptr);
00088
00089 static t_linked_rc_edge *alloc_linked_rc_edge(t_linked_rc_edge
00090 ** rc_edge_free_list_ptr);
00091
00092 static void free_linked_rc_edge(t_linked_rc_edge * rc_edge,
00093 t_linked_rc_edge ** rc_edge_free_list_ptr);
00094
00095 static float load_rc_tree_C(t_rc_node * rc_node);
00096
00097 static void load_rc_tree_T(t_rc_node * rc_node,
00098 float T_arrival);
00099
00100 static void load_one_net_delay(float **net_delay,
00101 int inet,
00102 t_linked_rc_ptr * rr_node_to_rc_node);
00103
00104 static void load_one_constant_net_delay(float **net_delay,
00105 int inet,
00106 float delay_value);
00107
00108 static void free_rc_tree(t_rc_node * rc_root,
00109 t_rc_node ** rc_node_free_list_ptr,
00110 t_linked_rc_edge ** rc_edge_free_list_ptr);
00111
00112 static void reset_rr_node_to_rc_node(t_linked_rc_ptr * rr_node_to_rc_node,
00113 int inet);
00114
00115 static void free_rc_node_free_list(t_rc_node * rc_node_free_list);
00116
00117 static void free_rc_edge_free_list(t_linked_rc_edge * rc_edge_free_list);
00118
00119
00120
00121
00122
00123
00124 float **
00125 alloc_net_delay(struct s_linked_vptr **chunk_list_head_ptr)
00126 {
00127
00128
00129
00130
00131
00132 float **net_delay;
00133 float *tmp_ptr;
00134 int inet;
00135 int chunk_bytes_avail;
00136 char *chunk_next_avail_mem;
00137
00138 *chunk_list_head_ptr = NULL;
00139 chunk_bytes_avail = 0;
00140 chunk_next_avail_mem = NULL;
00141
00142 net_delay = (float **)my_malloc(num_nets * sizeof(float *));
00143
00144 for(inet = 0; inet < num_nets; inet++)
00145 {
00146 tmp_ptr =
00147 (float *)my_chunk_malloc(((net[inet].num_sinks + 1) - 1) *
00148 sizeof(float), chunk_list_head_ptr,
00149 &chunk_bytes_avail,
00150 &chunk_next_avail_mem);
00151
00152 net_delay[inet] = tmp_ptr - 1;
00153 }
00154
00155 return (net_delay);
00156 }
00157
00158
00159 void
00160 free_net_delay(float **net_delay,
00161 struct s_linked_vptr **chunk_list_head_ptr)
00162 {
00163
00164
00165
00166 free(net_delay);
00167 free_chunk_memory(*chunk_list_head_ptr);
00168 *chunk_list_head_ptr = NULL;
00169 }
00170
00171
00172 void
00173 load_net_delay_from_routing(float **net_delay)
00174 {
00175
00176
00177
00178
00179
00180
00181
00182 t_rc_node *rc_node_free_list, *rc_root;
00183 t_linked_rc_edge *rc_edge_free_list;
00184 int inet;
00185 t_linked_rc_ptr *rr_node_to_rc_node;
00186
00187 rr_node_to_rc_node = (t_linked_rc_ptr *) my_calloc(num_rr_nodes,
00188 sizeof
00189 (t_linked_rc_ptr));
00190
00191 rc_node_free_list = NULL;
00192 rc_edge_free_list = NULL;
00193
00194 for(inet = 0; inet < num_nets; inet++)
00195 {
00196 if(net[inet].is_global)
00197 {
00198 load_one_constant_net_delay(net_delay, inet, 0.);
00199 }
00200 else
00201 {
00202 rc_root = alloc_and_load_rc_tree(inet, &rc_node_free_list,
00203 &rc_edge_free_list,
00204 rr_node_to_rc_node);
00205 load_rc_tree_C(rc_root);
00206 load_rc_tree_T(rc_root, 0.);
00207 load_one_net_delay(net_delay, inet, rr_node_to_rc_node);
00208 free_rc_tree(rc_root, &rc_node_free_list,
00209 &rc_edge_free_list);
00210 reset_rr_node_to_rc_node(rr_node_to_rc_node, inet);
00211 }
00212 }
00213
00214 free_rc_node_free_list(rc_node_free_list);
00215 free_rc_edge_free_list(rc_edge_free_list);
00216 free(rr_node_to_rc_node);
00217 }
00218
00219
00220 void
00221 load_constant_net_delay(float **net_delay,
00222 float delay_value)
00223 {
00224
00225
00226
00227
00228
00229
00230 int inet;
00231
00232 for(inet = 0; inet < num_nets; inet++)
00233 {
00234 if(net[inet].is_global)
00235 {
00236 load_one_constant_net_delay(net_delay, inet, 0.);
00237 }
00238 else
00239 {
00240 load_one_constant_net_delay(net_delay, inet, delay_value);
00241 }
00242 }
00243 }
00244
00245
00246 static t_rc_node *
00247 alloc_and_load_rc_tree(int inet,
00248 t_rc_node ** rc_node_free_list_ptr,
00249 t_linked_rc_edge ** rc_edge_free_list_ptr,
00250 t_linked_rc_ptr * rr_node_to_rc_node)
00251 {
00252
00253
00254
00255
00256 t_rc_node *curr_rc, *prev_rc, *root_rc;
00257 struct s_trace *tptr;
00258 int inode, prev_node;
00259 short iswitch;
00260 t_linked_rc_ptr *linked_rc_ptr;
00261
00262 root_rc = alloc_rc_node(rc_node_free_list_ptr);
00263 tptr = trace_head[inet];
00264
00265 if(tptr == NULL)
00266 {
00267 printf
00268 ("Error in alloc_and_load_rc_tree: Traceback for net %d doesn't "
00269 "exist.\n", inet);
00270 exit(1);
00271 }
00272
00273 inode = tptr->index;
00274 iswitch = tptr->iswitch;
00275 root_rc->inode = inode;
00276 root_rc->u.child_list = NULL;
00277 rr_node_to_rc_node[inode].rc_node = root_rc;
00278
00279 prev_rc = root_rc;
00280 tptr = tptr->next;
00281
00282 while(tptr != NULL)
00283 {
00284 inode = tptr->index;
00285
00286
00287
00288
00289 if(rr_node_to_rc_node[inode].rc_node == NULL)
00290 {
00291 curr_rc = alloc_rc_node(rc_node_free_list_ptr);
00292 add_to_rc_tree(prev_rc, curr_rc, iswitch, inode,
00293 rc_edge_free_list_ptr);
00294 rr_node_to_rc_node[inode].rc_node = curr_rc;
00295 prev_rc = curr_rc;
00296 }
00297
00298 else if(rr_node[inode].type != SINK)
00299 {
00300
00301 #ifdef DEBUG
00302 prev_node = prev_rc->inode;
00303 if(rr_node[prev_node].type != SINK)
00304 {
00305 printf
00306 ("Error in alloc_and_load_rc_tree: Routing of net %d is "
00307 "not a tree.\n", inet);
00308 exit(1);
00309 }
00310 #endif
00311
00312 prev_rc = rr_node_to_rc_node[inode].rc_node;
00313 }
00314
00315 else
00316 {
00317
00318
00319
00320
00321
00322
00323
00324
00325 curr_rc = alloc_rc_node(rc_node_free_list_ptr);
00326 add_to_rc_tree(prev_rc, curr_rc, iswitch, inode,
00327 rc_edge_free_list_ptr);
00328
00329 linked_rc_ptr = (t_linked_rc_ptr *)
00330 my_malloc(sizeof(t_linked_rc_ptr));
00331 linked_rc_ptr->next = rr_node_to_rc_node[inode].next;
00332 rr_node_to_rc_node[inode].next = linked_rc_ptr;
00333 linked_rc_ptr->rc_node = curr_rc;
00334
00335 prev_rc = curr_rc;
00336 }
00337 iswitch = tptr->iswitch;
00338 tptr = tptr->next;
00339 }
00340
00341 return (root_rc);
00342 }
00343
00344
00345 static void
00346 add_to_rc_tree(t_rc_node * parent_rc,
00347 t_rc_node * child_rc,
00348 short iswitch,
00349 int inode,
00350 t_linked_rc_edge ** rc_edge_free_list_ptr)
00351 {
00352
00353
00354
00355
00356
00357 t_linked_rc_edge *linked_rc_edge;
00358
00359 linked_rc_edge = alloc_linked_rc_edge(rc_edge_free_list_ptr);
00360
00361 linked_rc_edge->next = parent_rc->u.child_list;
00362 parent_rc->u.child_list = linked_rc_edge;
00363
00364 linked_rc_edge->child = child_rc;
00365 linked_rc_edge->iswitch = iswitch;
00366
00367 child_rc->u.child_list = NULL;
00368 child_rc->inode = inode;
00369 }
00370
00371
00372 static t_rc_node *
00373 alloc_rc_node(t_rc_node ** rc_node_free_list_ptr)
00374 {
00375
00376
00377
00378
00379 t_rc_node *rc_node;
00380
00381 rc_node = *rc_node_free_list_ptr;
00382
00383 if(rc_node != NULL)
00384 {
00385 *rc_node_free_list_ptr = rc_node->u.next;
00386 }
00387 else
00388 {
00389 rc_node = (t_rc_node *) my_malloc(sizeof(t_rc_node));
00390 }
00391
00392 return (rc_node);
00393 }
00394
00395
00396 static void
00397 free_rc_node(t_rc_node * rc_node,
00398 t_rc_node ** rc_node_free_list_ptr)
00399 {
00400
00401
00402
00403 rc_node->u.next = *rc_node_free_list_ptr;
00404 *rc_node_free_list_ptr = rc_node;
00405 }
00406
00407
00408 static t_linked_rc_edge *
00409 alloc_linked_rc_edge(t_linked_rc_edge ** rc_edge_free_list_ptr)
00410 {
00411
00412
00413
00414
00415 t_linked_rc_edge *linked_rc_edge;
00416
00417 linked_rc_edge = *rc_edge_free_list_ptr;
00418
00419 if(linked_rc_edge != NULL)
00420 {
00421 *rc_edge_free_list_ptr = linked_rc_edge->next;
00422 }
00423 else
00424 {
00425 linked_rc_edge = (t_linked_rc_edge *) my_malloc(sizeof
00426 (t_linked_rc_edge));
00427 }
00428
00429 return (linked_rc_edge);
00430 }
00431
00432
00433 static void
00434 free_linked_rc_edge(t_linked_rc_edge * rc_edge,
00435 t_linked_rc_edge ** rc_edge_free_list_ptr)
00436 {
00437
00438
00439
00440 rc_edge->next = *rc_edge_free_list_ptr;
00441 *rc_edge_free_list_ptr = rc_edge;
00442 }
00443
00444
00445 static float
00446 load_rc_tree_C(t_rc_node * rc_node)
00447 {
00448
00449
00450
00451
00452
00453 t_linked_rc_edge *linked_rc_edge;
00454 t_rc_node *child_node;
00455 int inode;
00456 short iswitch;
00457 float C, C_downstream;
00458
00459 linked_rc_edge = rc_node->u.child_list;
00460 inode = rc_node->inode;
00461 C = rr_node[inode].C;
00462
00463 while(linked_rc_edge != NULL)
00464 {
00465 iswitch = linked_rc_edge->iswitch;
00466 child_node = linked_rc_edge->child;
00467 C_downstream = load_rc_tree_C(child_node);
00468
00469 if(switch_inf[iswitch].buffered == FALSE)
00470 C += C_downstream;
00471
00472 linked_rc_edge = linked_rc_edge->next;
00473 }
00474
00475 rc_node->C_downstream = C;
00476 return (C);
00477 }
00478
00479
00480 static void
00481 load_rc_tree_T(t_rc_node * rc_node,
00482 float T_arrival)
00483 {
00484
00485
00486
00487
00488
00489
00490 float Tdel, Rmetal, Tchild;
00491 t_linked_rc_edge *linked_rc_edge;
00492 t_rc_node *child_node;
00493 short iswitch;
00494 int inode;
00495
00496 Tdel = T_arrival;
00497 inode = rc_node->inode;
00498 Rmetal = rr_node[inode].R;
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 Tdel += 0.5 * rc_node->C_downstream * Rmetal;
00513 rc_node->Tdel = Tdel;
00514
00515
00516
00517 linked_rc_edge = rc_node->u.child_list;
00518
00519 while(linked_rc_edge != NULL)
00520 {
00521 iswitch = linked_rc_edge->iswitch;
00522 child_node = linked_rc_edge->child;
00523
00524 Tchild = Tdel + switch_inf[iswitch].R * child_node->C_downstream;
00525 Tchild += switch_inf[iswitch].Tdel;
00526 load_rc_tree_T(child_node, Tchild);
00527
00528 linked_rc_edge = linked_rc_edge->next;
00529 }
00530 }
00531
00532
00533 static void
00534 load_one_net_delay(float **net_delay,
00535 int inet,
00536 t_linked_rc_ptr * rr_node_to_rc_node)
00537 {
00538
00539
00540
00541
00542 int ipin, inode;
00543 float Tmax;
00544 t_rc_node *rc_node;
00545 t_linked_rc_ptr *linked_rc_ptr, *next_ptr;
00546
00547 for(ipin = 1; ipin < (net[inet].num_sinks + 1); ipin++)
00548 {
00549
00550 inode = net_rr_terminals[inet][ipin];
00551
00552
00553 linked_rc_ptr = rr_node_to_rc_node[inode].next;
00554 rc_node = rr_node_to_rc_node[inode].rc_node;
00555 Tmax = rc_node->Tdel;
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566 if(linked_rc_ptr != NULL)
00567 {
00568
00569
00570
00571
00572
00573 do
00574 {
00575 rc_node = linked_rc_ptr->rc_node;
00576 if(rc_node->Tdel > Tmax)
00577 {
00578 Tmax = rc_node->Tdel;
00579 rr_node_to_rc_node[inode].rc_node =
00580 rc_node;
00581 }
00582 next_ptr = linked_rc_ptr->next;
00583 free(linked_rc_ptr);
00584 linked_rc_ptr = next_ptr;
00585 }
00586 while(linked_rc_ptr != NULL);
00587
00588 rr_node_to_rc_node[inode].next = NULL;
00589 }
00590
00591 net_delay[inet][ipin] = Tmax;
00592 }
00593 }
00594
00595
00596 static void
00597 load_one_constant_net_delay(float **net_delay,
00598 int inet,
00599 float delay_value)
00600 {
00601
00602
00603
00604 int ipin;
00605
00606 for(ipin = 1; ipin < (net[inet].num_sinks + 1); ipin++)
00607 net_delay[inet][ipin] = delay_value;
00608 }
00609
00610
00611 static void
00612 free_rc_tree(t_rc_node * rc_root,
00613 t_rc_node ** rc_node_free_list_ptr,
00614 t_linked_rc_edge ** rc_edge_free_list_ptr)
00615 {
00616
00617
00618
00619
00620 t_rc_node *rc_node, *child_node;
00621 t_linked_rc_edge *rc_edge, *next_edge;
00622
00623 rc_node = rc_root;
00624 rc_edge = rc_node->u.child_list;
00625
00626 while(rc_edge != NULL)
00627 {
00628 child_node = rc_edge->child;
00629 free_rc_tree(child_node, rc_node_free_list_ptr,
00630 rc_edge_free_list_ptr);
00631 next_edge = rc_edge->next;
00632 free_linked_rc_edge(rc_edge, rc_edge_free_list_ptr);
00633 rc_edge = next_edge;
00634 }
00635
00636 free_rc_node(rc_node, rc_node_free_list_ptr);
00637 }
00638
00639
00640 static void
00641 reset_rr_node_to_rc_node(t_linked_rc_ptr * rr_node_to_rc_node,
00642 int inet)
00643 {
00644
00645
00646
00647
00648
00649
00650 struct s_trace *tptr;
00651 int inode;
00652
00653 tptr = trace_head[inet];
00654
00655 while(tptr != NULL)
00656 {
00657 inode = tptr->index;
00658 rr_node_to_rc_node[inode].rc_node = NULL;
00659 tptr = tptr->next;
00660 }
00661 }
00662
00663
00664 static void
00665 free_rc_node_free_list(t_rc_node * rc_node_free_list)
00666 {
00667
00668
00669
00670 t_rc_node *rc_node, *next_node;
00671
00672 rc_node = rc_node_free_list;
00673
00674 while(rc_node != NULL)
00675 {
00676 next_node = rc_node->u.next;
00677 free(rc_node);
00678 rc_node = next_node;
00679 }
00680 }
00681
00682
00683
00684 static void
00685 free_rc_edge_free_list(t_linked_rc_edge * rc_edge_free_list)
00686 {
00687
00688
00689
00690 t_linked_rc_edge *rc_edge, *next_edge;
00691
00692 rc_edge = rc_edge_free_list;
00693
00694 while(rc_edge != NULL)
00695 {
00696 next_edge = rc_edge->next;
00697 free(rc_edge);
00698 rc_edge = next_edge;
00699 }
00700 }
00701
00702
00703 void
00704 print_net_delay(float **net_delay,
00705 char *fname)
00706 {
00707
00708
00709
00710 FILE *fp;
00711 int inet, ipin;
00712
00713 fp = my_fopen(fname, "w");
00714
00715 for(inet = 0; inet < num_nets; inet++)
00716 {
00717 fprintf(fp, "Net: %d.\n", inet);
00718 fprintf(fp, "Delays:");
00719
00720 for(ipin = 1; ipin < (net[inet].num_sinks + 1); ipin++)
00721 fprintf(fp, " %g", net_delay[inet][ipin]);
00722
00723 fprintf(fp, "\n\n");
00724 }
00725
00726 fclose(fp);
00727 }