00001 #include <stdio.h>
00002 #include <sys/types.h>
00003 #include "util.h"
00004 #include "vpr_types.h"
00005 #include "vpr_utils.h"
00006 #include "globals.h"
00007 #include "place_and_route.h"
00008 #include "mst.h"
00009 #include "place.h"
00010 #include "read_place.h"
00011 #include "route_export.h"
00012 #include "draw.h"
00013 #include "stats.h"
00014 #include "check_route.h"
00015 #include "rr_graph.h"
00016 #include "path_delay.h"
00017 #include "net_delay.h"
00018 #include "timing_place.h"
00019 #include <assert.h>
00020
00021
00022
00023 static int binary_search_place_and_route(struct s_placer_opts placer_opts,
00024 char *place_file,
00025 char *net_file,
00026 char *arch_file,
00027 char *route_file,
00028 boolean full_stats,
00029 boolean verify_binary_search,
00030 struct s_annealing_sched
00031 annealing_sched,
00032 struct s_router_opts router_opts,
00033 struct s_det_routing_arch
00034 det_routing_arch,
00035 t_segment_inf * segment_inf,
00036 t_timing_inf timing_inf,
00037 t_subblock_data * subblock_data_ptr,
00038 t_chan_width_dist chan_width_dist,
00039 t_mst_edge ** mst);
00040
00041 static float comp_width(t_chan * chan,
00042 float x,
00043 float separation);
00044
00045
00046 void post_place_sync(IN int num_blocks,
00047 INOUT const struct s_block block_list[],
00048 INOUT t_subblock_data * subblock_data_ptr);
00049
00050 void free_subblock_data(t_subblock_data * subblock_data_ptr);
00051
00052
00053
00054
00055 void
00056 place_and_route(enum e_operation operation,
00057 struct s_placer_opts placer_opts,
00058 char *place_file,
00059 char *net_file,
00060 char *arch_file,
00061 char *route_file,
00062 struct s_annealing_sched annealing_sched,
00063 struct s_router_opts router_opts,
00064 struct s_det_routing_arch det_routing_arch,
00065 t_segment_inf * segment_inf,
00066 t_timing_inf timing_inf,
00067 t_subblock_data * subblock_data_ptr,
00068 t_chan_width_dist chan_width_dist)
00069 {
00070
00071
00072
00073 char msg[BUFSIZE];
00074 int width_fac, inet, i;
00075 boolean success, Fc_clipped;
00076 float **net_delay, **net_slack;
00077 struct s_linked_vptr *net_delay_chunk_list_head;
00078 t_ivec **fb_opins_used_locally;
00079 t_mst_edge **mst = NULL;
00080 int max_pins_per_fb;
00081
00082 Fc_clipped = FALSE;
00083
00084 max_pins_per_fb = 0;
00085 for(i = 0; i < num_types; i++)
00086 {
00087 if(type_descriptors[i].num_pins > max_pins_per_fb)
00088 {
00089 max_pins_per_fb = type_descriptors[i].num_pins;
00090 }
00091 }
00092
00093 if(placer_opts.place_freq == PLACE_NEVER)
00094 {
00095
00096 read_place(place_file, net_file, arch_file, nx, ny, num_blocks,
00097 block);
00098 sync_grid_to_blocks(num_blocks, block, nx, ny, grid);
00099 }
00100 else
00101 {
00102 assert((PLACE_ONCE == placer_opts.place_freq) ||
00103 (PLACE_ALWAYS == placer_opts.place_freq));
00104
00105 try_place(placer_opts, annealing_sched, chan_width_dist,
00106 router_opts, det_routing_arch, segment_inf,
00107 timing_inf, subblock_data_ptr, &mst);
00108 print_place(place_file, net_file, arch_file);
00109 }
00110 post_place_sync(num_blocks, block, subblock_data_ptr);
00111
00112
00113 fflush(stdout);
00114 if(operation == PLACE_ONLY)
00115 return;
00116
00117 width_fac = router_opts.fixed_channel_width;
00118
00119
00120 if(NO_FIXED_CHANNEL_WIDTH == width_fac)
00121 {
00122 binary_search_place_and_route(placer_opts, place_file,
00123 net_file, arch_file, route_file,
00124 router_opts.full_stats, router_opts.verify_binary_search,
00125 annealing_sched, router_opts,
00126 det_routing_arch, segment_inf,
00127 timing_inf, subblock_data_ptr,
00128 chan_width_dist, mst);
00129 }
00130 else
00131 {
00132 if(det_routing_arch.directionality == UNI_DIRECTIONAL)
00133 {
00134 if(width_fac % 2 != 0)
00135 {
00136 printf
00137 ("Error: place_and_route.c: given odd chan width (%d) for udsd architecture\n",
00138 width_fac);
00139 exit(1);
00140 }
00141 }
00142
00143
00144
00145
00146
00147 fb_opins_used_locally = alloc_route_structs(*subblock_data_ptr);
00148
00149 if(timing_inf.timing_analysis_enabled)
00150 {
00151 net_slack =
00152 alloc_and_load_timing_graph(timing_inf,
00153 *subblock_data_ptr);
00154 net_delay = alloc_net_delay(&net_delay_chunk_list_head);
00155 }
00156 else
00157 {
00158 net_delay = NULL;
00159 net_slack = NULL;
00160 }
00161
00162 success =
00163 try_route(width_fac, router_opts, det_routing_arch,
00164 segment_inf, timing_inf, net_slack, net_delay,
00165 chan_width_dist, fb_opins_used_locally, mst,
00166 &Fc_clipped);
00167
00168 if(Fc_clipped)
00169 {
00170 printf
00171 ("Warning: Fc_output was too high and was clipped to full (maximum) connectivity.\n");
00172 }
00173
00174 if(success == FALSE)
00175 {
00176 printf
00177 ("Circuit is unrouteable with a channel width factor of %d\n\n",
00178 width_fac);
00179 sprintf(msg,
00180 "Routing failed with a channel width factor of %d. ILLEGAL routing shown.",
00181 width_fac);
00182 }
00183
00184 else
00185 {
00186 check_route(router_opts.route_type,
00187 det_routing_arch.num_switch,
00188 fb_opins_used_locally);
00189 get_serial_num();
00190
00191 printf
00192 ("Circuit successfully routed with a channel width factor of %d.\n\n",
00193 width_fac);
00194
00195 routing_stats(router_opts.full_stats, router_opts.route_type,
00196 det_routing_arch.num_switch, segment_inf,
00197 det_routing_arch.num_segment,
00198 det_routing_arch.R_minW_nmos,
00199 det_routing_arch.R_minW_pmos,
00200 det_routing_arch.directionality,
00201 timing_inf.timing_analysis_enabled,
00202 net_slack, net_delay, *subblock_data_ptr);
00203
00204 print_route(route_file);
00205
00206 #ifdef CREATE_ECHO_FILES
00207
00208 #endif
00209
00210 sprintf(msg,
00211 "Routing succeeded with a channel width factor of %d.\n\n",
00212 width_fac);
00213 }
00214 free_subblock_data(subblock_data_ptr);
00215
00216 init_draw_coords(max_pins_per_fb);
00217 update_screen(MAJOR, msg, ROUTING,
00218 timing_inf.timing_analysis_enabled);
00219
00220 if(timing_inf.timing_analysis_enabled)
00221 {
00222 assert(net_slack);
00223 free_timing_graph(net_slack);
00224
00225 assert(net_delay);
00226 free_net_delay(net_delay, &net_delay_chunk_list_head);
00227 }
00228
00229 free_route_structs(fb_opins_used_locally);
00230 fflush(stdout);
00231 }
00232
00233
00234 if(mst)
00235 {
00236 for(inet = 0; inet < num_nets; inet++)
00237 {
00238 assert(mst[inet]);
00239 free(mst[inet]);
00240 }
00241 free(mst);
00242 mst = NULL;
00243 }
00244
00245 }
00246
00247
00248
00249 static int
00250 binary_search_place_and_route(struct s_placer_opts placer_opts,
00251 char *place_file,
00252 char *net_file,
00253 char *arch_file,
00254 char *route_file,
00255 boolean full_stats,
00256 boolean verify_binary_search,
00257 struct s_annealing_sched annealing_sched,
00258 struct s_router_opts router_opts,
00259 struct s_det_routing_arch det_routing_arch,
00260 t_segment_inf * segment_inf,
00261 t_timing_inf timing_inf,
00262 t_subblock_data * subblock_data_ptr,
00263 t_chan_width_dist chan_width_dist,
00264 t_mst_edge ** mst)
00265 {
00266
00267
00268
00269
00270
00271 struct s_trace **best_routing;
00272 int current, low, high, final;
00273 int max_pins_per_fb, i;
00274 boolean success, prev_success, prev2_success, Fc_clipped = FALSE;
00275 char msg[BUFSIZE];
00276 float **net_delay, **net_slack;
00277 struct s_linked_vptr *net_delay_chunk_list_head;
00278 int try_w_limit;
00279 t_ivec **fb_opins_used_locally, **saved_clb_opins_used_locally;
00280
00281
00282 int attempt_count;
00283 int udsd_multiplier;
00284 int warnings;
00285
00286 t_graph_type graph_type;
00287
00288
00289
00290 if(router_opts.route_type == GLOBAL) {
00291 graph_type = GRAPH_GLOBAL;
00292 } else {
00293 graph_type = (det_routing_arch.directionality ==
00294 BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
00295 }
00296
00297 max_pins_per_fb = 0;
00298 for(i = 0; i < num_types; i++)
00299 {
00300 max_pins_per_fb =
00301 max(max_pins_per_fb, type_descriptors[i].num_pins);
00302 }
00303
00304 fb_opins_used_locally = alloc_route_structs(*subblock_data_ptr);
00305 best_routing = alloc_saved_routing(fb_opins_used_locally,
00306 &saved_clb_opins_used_locally);
00307
00308 if(timing_inf.timing_analysis_enabled)
00309 {
00310 net_slack =
00311 alloc_and_load_timing_graph(timing_inf, *subblock_data_ptr);
00312 net_delay = alloc_net_delay(&net_delay_chunk_list_head);
00313 }
00314 else
00315 {
00316 net_delay = NULL;
00317 net_slack = NULL;
00318 }
00319
00320
00321 if(det_routing_arch.directionality == BI_DIRECTIONAL)
00322 udsd_multiplier = 1;
00323 else
00324 udsd_multiplier = 2;
00325
00326
00327 if(router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH)
00328 {
00329 current = router_opts.fixed_channel_width + 5 * udsd_multiplier;
00330 low = router_opts.fixed_channel_width - 1 * udsd_multiplier;
00331 }
00332 else
00333 {
00334 current = max_pins_per_fb + max_pins_per_fb % 2;
00335 low = -1;
00336 }
00337
00338
00339 if(det_routing_arch.directionality == UNI_DIRECTIONAL)
00340 {
00341 if(current % 2 != 0)
00342 {
00343 printf
00344 ("Error: place_and_route.c: tried odd chan width (%d) for udsd architecture\n",
00345 current);
00346 exit(1);
00347 }
00348 }
00349
00350 else
00351 {
00352 if(det_routing_arch.Fs % 3)
00353 {
00354 printf("Fs must be three in bidirectional mode\n");
00355 exit(1);
00356 }
00357 }
00358
00359 high = -1;
00360 final = -1;
00361 try_w_limit = 0;
00362
00363 attempt_count = 0;
00364
00365 while(final == -1)
00366 {
00367
00368 printf("low, high, current %d %d %d\n", low, high, current);
00369 fflush(stdout);
00370
00371
00372
00373
00374 if(router_opts.fixed_channel_width != NO_FIXED_CHANNEL_WIDTH)
00375 {
00376 if(current > router_opts.fixed_channel_width * 4)
00377 {
00378 printf
00379 ("This circuit appears to be unroutable with the current "
00380 "router options. Last failed at %d\n", low);
00381 printf("Aborting routing procedure.\n");
00382 exit(1);
00383 }
00384 }
00385 else
00386 {
00387 if(current > 305)
00388 {
00389 printf
00390 ("This circuit appears to be unroutable with the current "
00391 "router options. Last failed at %d\n", low);
00392 printf("Aborting routing procedure.\n");
00393 exit(1);
00394 }
00395 }
00396
00397 if((current * 3) < det_routing_arch.Fs)
00398 {
00399 printf
00400 ("width factor is now below specified Fs. Stop search.\n");
00401 final = high;
00402 break;
00403 }
00404
00405 if(placer_opts.place_freq == PLACE_ALWAYS)
00406 {
00407 placer_opts.place_chan_width = current;
00408 try_place(placer_opts, annealing_sched, chan_width_dist,
00409 router_opts, det_routing_arch, segment_inf,
00410 timing_inf, subblock_data_ptr, &mst);
00411 }
00412 success =
00413 try_route(current, router_opts, det_routing_arch, segment_inf,
00414 timing_inf, net_slack, net_delay, chan_width_dist,
00415 fb_opins_used_locally, mst, &Fc_clipped);
00416 attempt_count++;
00417 fflush(stdout);
00418 #if 1
00419 if(success && (Fc_clipped == FALSE))
00420 {
00421 #else
00422 if(success
00423 && (Fc_clipped == FALSE
00424 || det_routing_arch.Fc_type == FRACTIONAL))
00425 {
00426 #endif
00427 high = current;
00428
00429
00430 if(Fc_clipped)
00431 {
00432 printf
00433 ("Warning: Fc_output was too high and was clipped to full (maximum) connectivity.\n");
00434 }
00435
00436
00437 #if 0
00438 if(placer_opts.place_freq == PLACE_ALWAYS)
00439 {
00440 print_place(place_file, net_file, arch_file);
00441 }
00442 #endif
00443
00444
00445 save_routing(best_routing, fb_opins_used_locally,
00446 saved_clb_opins_used_locally);
00447
00448 if((high - low) <= 1 * udsd_multiplier)
00449 final = high;
00450
00451 if(low != -1)
00452 {
00453 current = (high + low) / 2;
00454 }
00455 else
00456 {
00457 current = high / 2;
00458 }
00459 }
00460 else
00461 {
00462 if(success && Fc_clipped)
00463 {
00464 printf
00465 ("Routing rejected, Fc_output was too high.\n");
00466 success = FALSE;
00467 }
00468 low = current;
00469 if(high != -1)
00470 {
00471
00472 if((high - low) <= 1 * udsd_multiplier)
00473 final = high;
00474
00475 current = (high + low) / 2;
00476 }
00477 else
00478 {
00479 if(router_opts.fixed_channel_width !=
00480 NO_FIXED_CHANNEL_WIDTH)
00481 {
00482
00483 if(low <
00484 router_opts.fixed_channel_width + 30)
00485 {
00486 current =
00487 low + 5 * udsd_multiplier;
00488 }
00489 else
00490 {
00491 printf
00492 ("Aborting: Wneed = f(Fs) search found exceedingly large Wneed (at least %d)\n",
00493 low);
00494 exit(1);
00495 }
00496 }
00497 else
00498 {
00499 current = low * 2;
00500 }
00501 }
00502 }
00503 current = current + current % udsd_multiplier;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 if(verify_binary_search)
00516 {
00517
00518 printf
00519 ("\nVerifying that binary search found min. channel width ...\n");
00520
00521 prev_success = TRUE;
00522
00523 prev2_success = TRUE;
00524
00525 current = final - 2;
00526
00527 while(prev2_success || prev_success)
00528 {
00529 if((router_opts.fixed_channel_width !=
00530 NO_FIXED_CHANNEL_WIDTH)
00531 && (current < router_opts.fixed_channel_width))
00532 {
00533 break;
00534 }
00535 fflush(stdout);
00536 if(current < 1)
00537 break;
00538 if(placer_opts.place_freq == PLACE_ALWAYS)
00539 {
00540 placer_opts.place_chan_width = current;
00541 try_place(placer_opts, annealing_sched,
00542 chan_width_dist, router_opts,
00543 det_routing_arch, segment_inf,
00544 timing_inf, subblock_data_ptr, &mst);
00545 }
00546
00547 success =
00548 try_route(current, router_opts, det_routing_arch,
00549 segment_inf, timing_inf, net_slack,
00550 net_delay, chan_width_dist,
00551 fb_opins_used_locally, mst, &Fc_clipped);
00552
00553 if(success && Fc_clipped == FALSE)
00554 {
00555 final = current;
00556 save_routing(best_routing, fb_opins_used_locally,
00557 saved_clb_opins_used_locally);
00558
00559 if(placer_opts.place_freq == PLACE_ALWAYS)
00560 {
00561 print_place(place_file, net_file,
00562 arch_file);
00563 }
00564 }
00565
00566
00567 prev2_success = prev_success;
00568 prev_success = success;
00569 current--;
00570 if(det_routing_arch.directionality == UNI_DIRECTIONAL) {
00571 current--;
00572 }
00573 }
00574 }
00575
00576
00577
00578
00579
00580
00581 init_chan(final, chan_width_dist);
00582 #if 0
00583 if(placer_opts.place_freq == PLACE_ALWAYS)
00584 {
00585 printf("Reading best placement back in.\n");
00586 placer_opts.place_chan_width = final;
00587 read_place(place_file, net_file, arch_file, placer_opts,
00588 router_opts, chan_width_dist, det_routing_arch,
00589 segment_inf, timing_inf, subblock_data_ptr, &mst);
00590 }
00591 #endif
00592 free_rr_graph();
00593
00594 build_rr_graph(graph_type,
00595 num_types, type_descriptors, nx, ny, grid,
00596 chan_width_x[0], NULL,
00597 det_routing_arch.switch_block_type, det_routing_arch.Fs,
00598 det_routing_arch.num_segment, det_routing_arch.num_switch, segment_inf,
00599 det_routing_arch.global_route_switch,
00600 det_routing_arch.delayless_switch, timing_inf,
00601 det_routing_arch.wire_to_ipin_switch,
00602 router_opts.base_cost_type, &warnings);
00603
00604 restore_routing(best_routing, fb_opins_used_locally,
00605 saved_clb_opins_used_locally);
00606 check_route(router_opts.route_type, det_routing_arch.num_switch,
00607 fb_opins_used_locally);
00608 get_serial_num();
00609 if(Fc_clipped)
00610 {
00611 printf
00612 ("Warning: Best routing Fc_output too high, clipped to full (maximum) connectivity.\n");
00613 }
00614 printf("Best routing used a channel width factor of %d.\n\n", final);
00615
00616 routing_stats(full_stats, router_opts.route_type,
00617 det_routing_arch.num_switch, segment_inf,
00618 det_routing_arch.num_segment,
00619 det_routing_arch.R_minW_nmos,
00620 det_routing_arch.R_minW_pmos,
00621 det_routing_arch.directionality,
00622 timing_inf.timing_analysis_enabled, net_slack, net_delay,
00623 *subblock_data_ptr);
00624
00625 print_route(route_file);
00626
00627 #ifdef CREATE_ECHO_FILES
00628
00629 #endif
00630
00631 init_draw_coords(max_pins_per_fb);
00632 sprintf(msg, "Routing succeeded with a channel width factor of %d.",
00633 final);
00634 update_screen(MAJOR, msg, ROUTING, timing_inf.timing_analysis_enabled);
00635
00636 free_subblock_data(subblock_data_ptr);
00637
00638 if(timing_inf.timing_analysis_enabled)
00639 {
00640 free_timing_graph(net_slack);
00641 free_net_delay(net_delay, &net_delay_chunk_list_head);
00642 }
00643
00644 free_route_structs(fb_opins_used_locally);
00645 free_saved_routing(best_routing, saved_clb_opins_used_locally);
00646 fflush(stdout);
00647
00648 return (final);
00649 }
00650
00651
00652 void
00653 init_chan(int cfactor,
00654 t_chan_width_dist chan_width_dist)
00655 {
00656
00657
00658
00659
00660
00661
00662 float x, separation, chan_width_io;
00663 int nio, i;
00664 t_chan chan_x_dist, chan_y_dist;
00665
00666 chan_width_io = chan_width_dist.chan_width_io;
00667 chan_x_dist = chan_width_dist.chan_x_dist;
00668 chan_y_dist = chan_width_dist.chan_y_dist;
00669
00670
00671
00672 nio = (int)floor(cfactor * chan_width_io + 0.5);
00673 if(nio == 0)
00674 nio = 1;
00675
00676 chan_width_x[0] = chan_width_x[ny] = nio;
00677 chan_width_y[0] = chan_width_y[nx] = nio;
00678
00679 if(ny > 1)
00680 {
00681 separation = 1. / (ny - 2.);
00682 x = 0.;
00683 chan_width_x[1] = (int)floor(cfactor * comp_width(&chan_x_dist, x,
00684 separation) +
00685 0.5);
00686
00687
00688 chan_width_x[1] = max(chan_width_x[1], 1);
00689
00690 for(i = 1; i < ny - 1; i++)
00691 {
00692 x = (float)i / ((float)(ny - 2.));
00693 chan_width_x[i + 1] =
00694 (int)floor(cfactor *
00695 comp_width(&chan_x_dist, x,
00696 separation) + 0.5);
00697 chan_width_x[i + 1] = max(chan_width_x[i + 1], 1);
00698 }
00699 }
00700
00701 if(nx > 1)
00702 {
00703 separation = 1. / (nx - 2.);
00704 x = 0.;
00705 chan_width_y[1] = (int)floor(cfactor * comp_width(&chan_y_dist, x,
00706 separation) +
00707 0.5);
00708
00709 chan_width_y[1] = max(chan_width_y[1], 1);
00710
00711 for(i = 1; i < nx - 1; i++)
00712 {
00713 x = (float)i / ((float)(nx - 2.));
00714 chan_width_y[i + 1] =
00715 (int)floor(cfactor *
00716 comp_width(&chan_y_dist, x,
00717 separation) + 0.5);
00718 chan_width_y[i + 1] = max(chan_width_y[i + 1], 1);
00719 }
00720 }
00721 #ifdef VERBOSE
00722 printf("\nchan_width_x:\n");
00723 for(i = 0; i <= ny; i++)
00724 printf("%d ", chan_width_x[i]);
00725 printf("\n\nchan_width_y:\n");
00726 for(i = 0; i <= nx; i++)
00727 printf("%d ", chan_width_y[i]);
00728 printf("\n\n");
00729 #endif
00730
00731 }
00732
00733
00734 static float
00735 comp_width(t_chan * chan,
00736 float x,
00737 float separation)
00738 {
00739
00740
00741
00742
00743
00744
00745 float val;
00746
00747 switch (chan->type)
00748 {
00749
00750 case UNIFORM:
00751 val = chan->peak;
00752 break;
00753
00754 case GAUSSIAN:
00755 val = (x - chan->xpeak) * (x - chan->xpeak) / (2 * chan->width *
00756 chan->width);
00757 val = chan->peak * exp(-val);
00758 val += chan->dc;
00759 break;
00760
00761 case PULSE:
00762 val = (float)fabs((double)(x - chan->xpeak));
00763 if(val > chan->width / 2.)
00764 {
00765 val = 0;
00766 }
00767 else
00768 {
00769 val = chan->peak;
00770 }
00771 val += chan->dc;
00772 break;
00773
00774 case DELTA:
00775 val = x - chan->xpeak;
00776 if(val > -separation / 2. && val <= separation / 2.)
00777 val = chan->peak;
00778 else
00779 val = 0.;
00780 val += chan->dc;
00781 break;
00782
00783 default:
00784 printf("Error in comp_width: Unknown channel type %d.\n",
00785 chan->type);
00786 exit(1);
00787 break;
00788 }
00789
00790 return (val);
00791 }
00792
00793
00794
00795 void
00796 post_place_sync(IN int num_blocks,
00797 INOUT const struct s_block block_list[],
00798 INOUT t_subblock_data * subblock_data_ptr)
00799 {
00800 int iblk, j, k, inet;
00801 t_type_ptr type;
00802 int max_num_block_pins;
00803 t_subblock **subblock_inf;
00804
00805 subblock_inf = subblock_data_ptr->subblock_inf;
00806
00807
00808
00809 for(iblk = 0; iblk < num_blocks; ++iblk)
00810 {
00811 type = block[iblk].type;
00812 assert(type->num_pins % type->capacity == 0);
00813 max_num_block_pins = type->num_pins / type->capacity;
00814
00815
00816 for(j = 0; j < max_num_block_pins; j++)
00817 {
00818 inet = block[iblk].nets[j];
00819 if(inet != OPEN && block[iblk].z > 0)
00820 {
00821 assert(block[iblk].
00822 nets[j +
00823 block[iblk].z * max_num_block_pins] ==
00824 OPEN);
00825 block[iblk].nets[j +
00826 block[iblk].z *
00827 max_num_block_pins] =
00828 block[iblk].nets[j];
00829 block[iblk].nets[j] = OPEN;
00830 for(k = 0; k < type->num_pins; k++)
00831 {
00832 if(net[inet].node_block[k] == iblk)
00833 {
00834 assert(net[inet].
00835 node_block_pin[k] == j);
00836 net[inet].node_block_pin[k] =
00837 j +
00838 block[iblk].z *
00839 max_num_block_pins;
00840 break;
00841 }
00842 }
00843 }
00844 }
00845
00846
00847 for(j = 0; j < subblock_data_ptr->num_subblocks_per_block[iblk];
00848 j++)
00849 {
00850 for(k = 0; k < type->max_subblock_inputs; k++)
00851 {
00852 if(subblock_inf[iblk][j].inputs[k] != OPEN)
00853 {
00854 subblock_inf[iblk][j].inputs[k] =
00855 subblock_inf[iblk][j].inputs[k] +
00856 block[iblk].z * max_num_block_pins;
00857 }
00858 }
00859 for(k = 0; k < type->max_subblock_outputs; k++)
00860 {
00861 if(subblock_inf[iblk][j].outputs[k] != OPEN)
00862 {
00863 subblock_inf[iblk][j].outputs[k] =
00864 subblock_inf[iblk][j].outputs[k] +
00865 block[iblk].z * max_num_block_pins;
00866 }
00867 }
00868 if(subblock_inf[iblk][j].clock != OPEN)
00869 {
00870 subblock_inf[iblk][j].clock =
00871 subblock_inf[iblk][j].clock +
00872 block[iblk].z * max_num_block_pins;
00873 }
00874 }
00875 }
00876 }
00877
00878 void
00879 free_subblock_data(t_subblock_data * subblock_data_ptr)
00880 {
00881 int i, j;
00882
00883
00884 for(i = 0; i < num_blocks; i++) {
00885 if(subblock_data_ptr->subblock_inf[i] != NULL) {
00886 for(j = 0; j < subblock_data_ptr->num_subblocks_per_block[i]; j++) {
00887 free(subblock_data_ptr->subblock_inf[i][j].name);
00888 free(subblock_data_ptr->subblock_inf[i][j].outputs);
00889 free(subblock_data_ptr->subblock_inf[i][j].inputs);
00890 }
00891 free(subblock_data_ptr->subblock_inf[i]);
00892
00893 }
00894 }
00895 free(subblock_data_ptr->subblock_inf);
00896 free(subblock_data_ptr->num_subblocks_per_block);
00897
00898
00899 subblock_data_ptr->num_subblocks_per_block = NULL;
00900 subblock_data_ptr->subblock_inf = NULL;
00901 }