Go to the source code of this file.
Functions | |
void | try_place (struct s_placer_opts placer_opts, struct s_annealing_sched annealing_sched, t_chan_width_dist chan_width_dist, struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf, t_subblock_data *subblock_data_ptr, t_mst_edge ***mst) |
void try_place | ( | struct s_placer_opts | placer_opts, | |
struct s_annealing_sched | annealing_sched, | |||
t_chan_width_dist | chan_width_dist, | |||
struct s_router_opts | router_opts, | |||
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf, | |||
t_subblock_data * | subblock_data_ptr, | |||
t_mst_edge *** | mst | |||
) |
Definition at line 296 of file place.c.
00305 { 00306 00307 /* Does almost all the work of placing a circuit. Width_fac gives the * 00308 * width of the widest channel. Place_cost_exp says what exponent the * 00309 * width should be taken to when calculating costs. This allows a * 00310 * greater bias for anisotropic architectures. Place_cost_type * 00311 * determines which cost function is used. num_regions is used only * 00312 * the place_cost_type is NONLINEAR_CONG. */ 00313 00314 00315 int tot_iter, inner_iter, success_sum; 00316 int move_lim, moves_since_cost_recompute, width_fac; 00317 float t, success_rat, rlim, d_max, est_crit; 00318 float cost, timing_cost, bb_cost, new_bb_cost, new_timing_cost; 00319 float delay_cost, new_delay_cost, place_delay_value; 00320 float inverse_prev_bb_cost, inverse_prev_timing_cost; 00321 float oldt; 00322 double av_cost, av_bb_cost, av_timing_cost, av_delay_cost, 00323 sum_of_squares, std_dev; 00324 float **old_region_occ_x, **old_region_occ_y; 00325 char msg[BUFSIZE]; 00326 boolean fixed_pins; /* Can pads move or not? */ 00327 int num_connections; 00328 int inet, ipin, outer_crit_iter_count, inner_crit_iter_count, 00329 inner_recompute_limit; 00330 float **net_slack, **net_delay; 00331 float crit_exponent; 00332 float first_rlim, final_rlim, inverse_delta_rlim; 00333 float **remember_net_delay_original_ptr; /*used to free net_delay if it is re-assigned */ 00334 00335 int *x_lookup; /* Used to quickly determine valid swap columns */ 00336 00337 /* Allocated here because it goes into timing critical code where each memory allocation is expensive */ 00338 x_lookup = my_malloc(nx * sizeof(int)); 00339 00340 remember_net_delay_original_ptr = NULL; /*prevents compiler warning */ 00341 00342 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00343 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE || 00344 placer_opts.enable_timing_computations) 00345 { 00346 /*do this before the initial placement to avoid messing up the initial placement */ 00347 alloc_lookups_and_criticalities(chan_width_dist, 00348 router_opts, 00349 det_routing_arch, 00350 segment_inf, 00351 timing_inf, 00352 *subblock_data_ptr, 00353 &net_delay, &net_slack); 00354 00355 remember_net_delay_original_ptr = net_delay; 00356 00357 /*#define PRINT_LOWER_BOUND */ 00358 #ifdef PRINT_LOWER_BOUND 00359 /*print the crit_path, assuming delay between blocks that are* 00360 *block_dist apart*/ 00361 00362 if(placer_opts.block_dist <= nx) 00363 place_delay_value = 00364 delta_clb_to_clb[placer_opts.block_dist][0]; 00365 else if(placer_opts.block_dist <= ny) 00366 place_delay_value = 00367 delta_clb_to_clb[0][placer_opts.block_dist]; 00368 else 00369 place_delay_value = delta_clb_to_clb[nx][ny]; 00370 00371 printf("\nLower bound assuming delay of %g\n", place_delay_value); 00372 00373 load_constant_net_delay(net_delay, place_delay_value); 00374 load_timing_graph_net_delays(net_delay); 00375 d_max = load_net_slack(net_slack, 0); 00376 00377 #ifdef CREATE_ECHO_FILES 00378 print_critical_path("Placement_Lower_Bound.echo"); 00379 print_sink_delays("Placement_Lower_Bound_Sink_Delays.echo"); 00380 #endif /* CREATE_ECHO_FILES */ 00381 00382 /*also print sink delays assuming 0 delay between blocks, 00383 * this tells us how much logic delay is on each path */ 00384 00385 load_constant_net_delay(net_delay, 0); 00386 load_timing_graph_net_delays(net_delay); 00387 d_max = load_net_slack(net_slack, 0); 00388 00389 #ifdef CREATE_ECHO_FILES 00390 print_sink_delays("Placement_Logic_Sink_Delays.echo"); 00391 #endif /* CREATE_ECHO_FILES */ 00392 #endif 00393 00394 } 00395 00396 width_fac = placer_opts.place_chan_width; 00397 if(placer_opts.pad_loc_type == FREE) 00398 fixed_pins = FALSE; 00399 else 00400 fixed_pins = TRUE; 00401 00402 init_chan(width_fac, chan_width_dist); 00403 00404 alloc_and_load_placement_structs(placer_opts.place_cost_type, 00405 placer_opts.num_regions, 00406 placer_opts.place_cost_exp, 00407 &old_region_occ_x, &old_region_occ_y, 00408 placer_opts); 00409 00410 initial_placement(placer_opts.pad_loc_type, placer_opts.pad_loc_file); 00411 init_draw_coords((float)width_fac); 00412 00413 /* Storing the number of pins on each type of block makes the swap routine * 00414 * slightly more efficient. */ 00415 00416 /* Gets initial cost and loads bounding boxes. */ 00417 00418 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00419 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE) 00420 { 00421 bb_cost = comp_bb_cost(NORMAL, placer_opts.place_cost_type, 00422 placer_opts.num_regions); 00423 00424 crit_exponent = placer_opts.td_place_exp_first; /*this will be modified when rlim starts to change */ 00425 00426 compute_net_pin_index_values(); 00427 00428 num_connections = count_connections(); 00429 printf 00430 ("\nThere are %d point to point connections in this circuit\n\n", 00431 num_connections); 00432 00433 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE) 00434 { 00435 for(inet = 0; inet < num_nets; inet++) 00436 for(ipin = 1; ipin <= net[inet].num_sinks; ipin++) 00437 timing_place_crit[inet][ipin] = 0; /*dummy crit values */ 00438 00439 comp_td_costs(&timing_cost, &delay_cost); /*first pass gets delay_cost, which is used 00440 * in criticality computations in the next call 00441 * to comp_td_costs. */ 00442 place_delay_value = delay_cost / num_connections; /*used for computing criticalities */ 00443 load_constant_net_delay(net_delay, place_delay_value); 00444 00445 } 00446 else 00447 place_delay_value = 0; 00448 00449 00450 if(placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE) 00451 { 00452 net_delay = point_to_point_delay_cost; /*this keeps net_delay up to date with * 00453 * *the same values that the placer is using * 00454 * *point_to_point_delay_cost is computed each* 00455 * *time that comp_td_costs is called, and is * 00456 * *also updated after any swap is accepted */ 00457 } 00458 00459 00460 load_timing_graph_net_delays(net_delay); 00461 d_max = load_net_slack(net_slack, 0); 00462 load_criticalities(placer_opts, net_slack, d_max, crit_exponent); 00463 outer_crit_iter_count = 1; 00464 00465 /*now we can properly compute costs */ 00466 comp_td_costs(&timing_cost, &delay_cost); /*also puts proper values into point_to_point_delay_cost */ 00467 00468 inverse_prev_timing_cost = 1 / timing_cost; 00469 inverse_prev_bb_cost = 1 / bb_cost; 00470 cost = 1; /*our new cost function uses normalized values of */ 00471 /*bb_cost and timing_cost, the value of cost will be reset */ 00472 /*to 1 at each temperature when *_TIMING_DRIVEN_PLACE is true */ 00473 } 00474 else 00475 { /*BOUNDING_BOX_PLACE */ 00476 cost = bb_cost = comp_bb_cost(NORMAL, placer_opts.place_cost_type, 00477 placer_opts.num_regions); 00478 timing_cost = 0; 00479 delay_cost = 0; 00480 place_delay_value = 0; 00481 outer_crit_iter_count = 0; 00482 num_connections = 0; 00483 d_max = 0; 00484 crit_exponent = 0; 00485 00486 inverse_prev_timing_cost = 0; /*inverses not used */ 00487 inverse_prev_bb_cost = 0; 00488 } 00489 00490 move_lim = (int)(annealing_sched.inner_num * pow(num_blocks, 1.3333)); 00491 00492 if(placer_opts.inner_loop_recompute_divider != 0) 00493 inner_recompute_limit = (int)(0.5 + (float)move_lim / 00494 (float)placer_opts. 00495 inner_loop_recompute_divider); 00496 else /*don't do an inner recompute */ 00497 inner_recompute_limit = move_lim + 1; 00498 00499 00500 /* Sometimes I want to run the router with a random placement. Avoid * 00501 * using 0 moves to stop division by 0 and 0 length vector problems, * 00502 * by setting move_lim to 1 (which is still too small to do any * 00503 * significant optimization). */ 00504 00505 if(move_lim <= 0) 00506 move_lim = 1; 00507 00508 rlim = (float)max(nx, ny); 00509 00510 first_rlim = rlim; /*used in timing-driven placement for exponent computation */ 00511 final_rlim = 1; 00512 inverse_delta_rlim = 1 / (first_rlim - final_rlim); 00513 00514 t = starting_t(&cost, &bb_cost, &timing_cost, 00515 placer_opts.place_cost_type, 00516 old_region_occ_x, old_region_occ_y, 00517 placer_opts.num_regions, fixed_pins, annealing_sched, 00518 move_lim, rlim, placer_opts.place_algorithm, 00519 placer_opts.timing_tradeoff, inverse_prev_bb_cost, 00520 inverse_prev_timing_cost, &delay_cost); 00521 tot_iter = 0; 00522 moves_since_cost_recompute = 0; 00523 printf 00524 ("Initial Placement Cost: %g bb_cost: %g td_cost: %g delay_cost: %g\n\n", 00525 cost, bb_cost, timing_cost, delay_cost); 00526 00527 #ifndef SPEC 00528 printf 00529 ("%11s %10s %11s %11s %11s %11s %11s %9s %8s %7s %7s %10s %7s\n", 00530 "T", "Cost", "Av. BB Cost", "Av. TD Cost", "Av Tot Del", 00531 "P to P Del", "d_max", "Ac Rate", "Std Dev", "R limit", "Exp", 00532 "Tot. Moves", "Alpha"); 00533 printf 00534 ("%11s %10s %11s %11s %11s %11s %11s %9s %8s %7s %7s %10s %7s\n", 00535 "--------", "----------", "-----------", "-----------", 00536 "---------", "----------", "-----", "-------", "-------", 00537 "-------", "-------", "----------", "-----"); 00538 #endif 00539 00540 sprintf(msg, 00541 "Initial Placement. Cost: %g BB Cost: %g TD Cost %g Delay Cost: %g " 00542 "\t d_max %g Channel Factor: %d", cost, bb_cost, timing_cost, 00543 delay_cost, d_max, width_fac); 00544 update_screen(MAJOR, msg, PLACEMENT, FALSE); 00545 00546 while(exit_crit(t, cost, annealing_sched) == 0) 00547 { 00548 00549 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00550 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE) 00551 { 00552 cost = 1; 00553 } 00554 00555 av_cost = 0.; 00556 av_bb_cost = 0.; 00557 av_delay_cost = 0.; 00558 av_timing_cost = 0.; 00559 sum_of_squares = 0.; 00560 success_sum = 0; 00561 00562 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00563 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE) 00564 { 00565 00566 if(outer_crit_iter_count >= 00567 placer_opts.recompute_crit_iter 00568 || placer_opts.inner_loop_recompute_divider != 0) 00569 { 00570 #ifdef VERBOSE 00571 printf("Outer Loop Recompute Criticalities\n"); 00572 #endif 00573 place_delay_value = delay_cost / num_connections; 00574 00575 if(placer_opts.place_algorithm == 00576 NET_TIMING_DRIVEN_PLACE) 00577 load_constant_net_delay(net_delay, 00578 place_delay_value); 00579 /*note, for path_based, the net delay is not updated since it is current, 00580 *because it accesses point_to_point_delay array */ 00581 00582 load_timing_graph_net_delays(net_delay); 00583 d_max = load_net_slack(net_slack, 0); 00584 load_criticalities(placer_opts, net_slack, d_max, 00585 crit_exponent); 00586 /*recompute costs from scratch, based on new criticalities */ 00587 comp_td_costs(&timing_cost, &delay_cost); 00588 outer_crit_iter_count = 0; 00589 } 00590 outer_crit_iter_count++; 00591 00592 /*at each temperature change we update these values to be used */ 00593 /*for normalizing the tradeoff between timing and wirelength (bb) */ 00594 inverse_prev_bb_cost = 1 / bb_cost; 00595 inverse_prev_timing_cost = 1 / timing_cost; 00596 } 00597 00598 inner_crit_iter_count = 1; 00599 00600 for(inner_iter = 0; inner_iter < move_lim; inner_iter++) 00601 { 00602 if(try_swap(t, &cost, &bb_cost, &timing_cost, 00603 rlim, placer_opts.place_cost_type, 00604 old_region_occ_x, old_region_occ_y, 00605 placer_opts.num_regions, fixed_pins, 00606 placer_opts.place_algorithm, 00607 placer_opts.timing_tradeoff, 00608 inverse_prev_bb_cost, 00609 inverse_prev_timing_cost, &delay_cost, 00610 x_lookup) == 1) 00611 { 00612 success_sum++; 00613 av_cost += cost; 00614 av_bb_cost += bb_cost; 00615 av_timing_cost += timing_cost; 00616 av_delay_cost += delay_cost; 00617 sum_of_squares += cost * cost; 00618 } 00619 00620 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE 00621 || placer_opts.place_algorithm == 00622 PATH_TIMING_DRIVEN_PLACE) 00623 { 00624 00625 if(inner_crit_iter_count >= inner_recompute_limit 00626 && inner_iter != move_lim - 1) 00627 { /*on last iteration don't recompute */ 00628 00629 inner_crit_iter_count = 0; 00630 #ifdef VERBOSE 00631 printf 00632 ("Inner Loop Recompute Criticalities\n"); 00633 #endif 00634 if(placer_opts.place_algorithm == 00635 NET_TIMING_DRIVEN_PLACE) 00636 { 00637 place_delay_value = 00638 delay_cost / num_connections; 00639 load_constant_net_delay(net_delay, 00640 place_delay_value); 00641 } 00642 00643 load_timing_graph_net_delays(net_delay); 00644 d_max = load_net_slack(net_slack, 0); 00645 load_criticalities(placer_opts, net_slack, 00646 d_max, crit_exponent); 00647 comp_td_costs(&timing_cost, &delay_cost); 00648 } 00649 inner_crit_iter_count++; 00650 } 00651 #ifdef VERBOSE 00652 printf 00653 ("t = %g cost = %g bb_cost = %g timing_cost = %g move = %d dmax = %g\n", 00654 t, cost, bb_cost, timing_cost, inner_iter, d_max); 00655 if(fabs 00656 (bb_cost - 00657 comp_bb_cost(CHECK, placer_opts.place_cost_type, 00658 placer_opts.num_regions)) > 00659 bb_cost * ERROR_TOL) 00660 exit(1); 00661 #endif 00662 } 00663 00664 /* Lines below prevent too much round-off error from accumulating * 00665 * in the cost over many iterations. This round-off can lead to * 00666 * error checks failing because the cost is different from what * 00667 * you get when you recompute from scratch. */ 00668 00669 moves_since_cost_recompute += move_lim; 00670 if(moves_since_cost_recompute > MAX_MOVES_BEFORE_RECOMPUTE) 00671 { 00672 new_bb_cost = 00673 recompute_bb_cost(placer_opts.place_cost_type, 00674 placer_opts.num_regions); 00675 if(fabs(new_bb_cost - bb_cost) > bb_cost * ERROR_TOL) 00676 { 00677 printf 00678 ("Error in try_place: new_bb_cost = %g, old bb_cost = %g.\n", 00679 new_bb_cost, bb_cost); 00680 exit(1); 00681 } 00682 bb_cost = new_bb_cost; 00683 00684 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE 00685 || placer_opts.place_algorithm == 00686 PATH_TIMING_DRIVEN_PLACE) 00687 { 00688 comp_td_costs(&new_timing_cost, &new_delay_cost); 00689 if(fabs(new_timing_cost - timing_cost) > 00690 timing_cost * ERROR_TOL) 00691 { 00692 printf 00693 ("Error in try_place: new_timing_cost = %g, old timing_cost = %g.\n", 00694 new_timing_cost, timing_cost); 00695 exit(1); 00696 } 00697 if(fabs(new_delay_cost - delay_cost) > 00698 delay_cost * ERROR_TOL) 00699 { 00700 printf 00701 ("Error in try_place: new_delay_cost = %g, old delay_cost = %g.\n", 00702 new_delay_cost, delay_cost); 00703 exit(1); 00704 } 00705 timing_cost = new_timing_cost; 00706 } 00707 00708 if(placer_opts.place_algorithm == BOUNDING_BOX_PLACE) 00709 { 00710 cost = new_bb_cost; 00711 } 00712 moves_since_cost_recompute = 0; 00713 } 00714 00715 tot_iter += move_lim; 00716 success_rat = ((float)success_sum) / move_lim; 00717 if(success_sum == 0) 00718 { 00719 av_cost = cost; 00720 av_bb_cost = bb_cost; 00721 av_timing_cost = timing_cost; 00722 av_delay_cost = delay_cost; 00723 } 00724 else 00725 { 00726 av_cost /= success_sum; 00727 av_bb_cost /= success_sum; 00728 av_timing_cost /= success_sum; 00729 av_delay_cost /= success_sum; 00730 } 00731 std_dev = get_std_dev(success_sum, sum_of_squares, av_cost); 00732 00733 #ifndef SPEC 00734 printf 00735 ("%11.5g %10.6g %11.6g %11.6g %11.6g %11.6g %11.4g %9.4g %8.3g %7.4g %7.4g %10d ", 00736 t, av_cost, av_bb_cost, av_timing_cost, av_delay_cost, 00737 place_delay_value, d_max, success_rat, std_dev, rlim, 00738 crit_exponent, tot_iter); 00739 #endif 00740 00741 oldt = t; /* for finding and printing alpha. */ 00742 update_t(&t, std_dev, rlim, success_rat, annealing_sched); 00743 00744 #ifndef SPEC 00745 printf("%7.4g\n", t / oldt); 00746 #endif 00747 00748 sprintf(msg, 00749 "Cost: %g BB Cost %g TD Cost %g Temperature: %g d_max: %g", 00750 cost, bb_cost, timing_cost, t, d_max); 00751 update_screen(MINOR, msg, PLACEMENT, FALSE); 00752 update_rlim(&rlim, success_rat); 00753 00754 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00755 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE) 00756 { 00757 crit_exponent = 00758 (1 - 00759 (rlim - 00760 final_rlim) * inverse_delta_rlim) * 00761 (placer_opts.td_place_exp_last - 00762 placer_opts.td_place_exp_first) + 00763 placer_opts.td_place_exp_first; 00764 } 00765 #ifdef VERBOSE 00766 dump_clbs(); 00767 #endif 00768 } 00769 00770 t = 0; /* freeze out */ 00771 av_cost = 0.; 00772 av_bb_cost = 0.; 00773 av_timing_cost = 0.; 00774 sum_of_squares = 0.; 00775 av_delay_cost = 0.; 00776 success_sum = 0; 00777 00778 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00779 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE) 00780 { 00781 /*at each temperature change we update these values to be used */ 00782 /*for normalizing the tradeoff between timing and wirelength (bb) */ 00783 if(outer_crit_iter_count >= placer_opts.recompute_crit_iter || 00784 placer_opts.inner_loop_recompute_divider != 0) 00785 { 00786 00787 #ifdef VERBOSE 00788 printf("Outer Loop Recompute Criticalities\n"); 00789 #endif 00790 place_delay_value = delay_cost / num_connections; 00791 00792 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE) 00793 load_constant_net_delay(net_delay, place_delay_value); 00794 00795 load_timing_graph_net_delays(net_delay); 00796 d_max = load_net_slack(net_slack, 0); 00797 load_criticalities(placer_opts, net_slack, d_max, 00798 crit_exponent); 00799 /*recompute criticaliies */ 00800 comp_td_costs(&timing_cost, &delay_cost); 00801 outer_crit_iter_count = 0; 00802 } 00803 outer_crit_iter_count++; 00804 00805 inverse_prev_bb_cost = 1 / (bb_cost); 00806 inverse_prev_timing_cost = 1 / (timing_cost); 00807 } 00808 00809 inner_crit_iter_count = 1; 00810 00811 for(inner_iter = 0; inner_iter < move_lim; inner_iter++) 00812 { 00813 if(try_swap(t, &cost, &bb_cost, &timing_cost, 00814 rlim, placer_opts.place_cost_type, 00815 old_region_occ_x, old_region_occ_y, 00816 placer_opts.num_regions, fixed_pins, 00817 placer_opts.place_algorithm, 00818 placer_opts.timing_tradeoff, inverse_prev_bb_cost, 00819 inverse_prev_timing_cost, &delay_cost, x_lookup) == 1) 00820 { 00821 success_sum++; 00822 av_cost += cost; 00823 av_bb_cost += bb_cost; 00824 av_delay_cost += delay_cost; 00825 av_timing_cost += timing_cost; 00826 sum_of_squares += cost * cost; 00827 00828 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE 00829 || placer_opts.place_algorithm == 00830 PATH_TIMING_DRIVEN_PLACE) 00831 { 00832 00833 if(inner_crit_iter_count >= inner_recompute_limit 00834 && inner_iter != move_lim - 1) 00835 { 00836 00837 inner_crit_iter_count = 0; 00838 #ifdef VERBOSE 00839 printf 00840 ("Inner Loop Recompute Criticalities\n"); 00841 #endif 00842 if(placer_opts.place_algorithm == 00843 NET_TIMING_DRIVEN_PLACE) 00844 { 00845 place_delay_value = 00846 delay_cost / num_connections; 00847 load_constant_net_delay(net_delay, 00848 place_delay_value); 00849 } 00850 00851 load_timing_graph_net_delays(net_delay); 00852 d_max = load_net_slack(net_slack, 0); 00853 load_criticalities(placer_opts, net_slack, 00854 d_max, crit_exponent); 00855 comp_td_costs(&timing_cost, &delay_cost); 00856 } 00857 inner_crit_iter_count++; 00858 } 00859 } 00860 #ifdef VERBOSE 00861 printf("t = %g cost = %g move = %d\n", t, cost, tot_iter); 00862 #endif 00863 } 00864 tot_iter += move_lim; 00865 success_rat = ((float)success_sum) / move_lim; 00866 if(success_sum == 0) 00867 { 00868 av_cost = cost; 00869 av_bb_cost = bb_cost; 00870 av_delay_cost = delay_cost; 00871 av_timing_cost = timing_cost; 00872 } 00873 else 00874 { 00875 av_cost /= success_sum; 00876 av_bb_cost /= success_sum; 00877 av_delay_cost /= success_sum; 00878 av_timing_cost /= success_sum; 00879 } 00880 00881 std_dev = get_std_dev(success_sum, sum_of_squares, av_cost); 00882 00883 00884 #ifndef SPEC 00885 printf 00886 ("%11.5g %10.6g %11.6g %11.6g %11.6g %11.6g %11.4g %9.4g %8.3g %7.4g %7.4g %10d \n\n", 00887 t, av_cost, av_bb_cost, av_timing_cost, av_delay_cost, 00888 place_delay_value, d_max, success_rat, std_dev, rlim, 00889 crit_exponent, tot_iter); 00890 00891 #endif 00892 00893 #ifdef VERBOSE 00894 dump_clbs(); 00895 #endif 00896 00897 check_place(bb_cost, timing_cost, placer_opts.place_cost_type, 00898 placer_opts.num_regions, placer_opts.place_algorithm, 00899 delay_cost); 00900 00901 if(placer_opts.enable_timing_computations && 00902 placer_opts.place_algorithm == BOUNDING_BOX_PLACE) 00903 { 00904 /*need this done since the timing data has not been kept up to date* 00905 *in bounding_box mode */ 00906 for(inet = 0; inet < num_nets; inet++) 00907 for(ipin = 1; ipin <= net[inet].num_sinks; ipin++) 00908 timing_place_crit[inet][ipin] = 0; /*dummy crit values */ 00909 comp_td_costs(&timing_cost, &delay_cost); /*computes point_to_point_delay_cost */ 00910 } 00911 00912 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00913 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE || 00914 placer_opts.enable_timing_computations) 00915 { 00916 net_delay = point_to_point_delay_cost; /*this makes net_delay up to date with * 00917 *the same values that the placer is using*/ 00918 load_timing_graph_net_delays(net_delay); 00919 est_crit = load_net_slack(net_slack, 0); 00920 #ifdef CREATE_ECHO_FILES 00921 /* print_sink_delays("placement_sink_delays.echo"); */ 00922 print_net_slack("placement_net_slacks.echo", net_slack); 00923 print_critical_path("placement_crit_path.echo", 00924 *subblock_data_ptr); 00925 #endif /* CREATE_ECHO_FILES */ 00926 printf("Placement Estimated Crit Path Delay: %g\n\n", est_crit); 00927 } 00928 00929 00930 sprintf(msg, 00931 "Placement. Cost: %g bb_cost: %g td_cost: %g Channel Factor: %d d_max: %g", 00932 cost, bb_cost, timing_cost, width_fac, d_max); 00933 printf 00934 ("Placement. Cost: %g bb_cost: %g td_cost: %g delay_cost: %g.\n", 00935 cost, bb_cost, timing_cost, delay_cost); 00936 update_screen(MAJOR, msg, PLACEMENT, FALSE); 00937 00938 #ifdef SPEC 00939 printf("Total moves attempted: %d.0\n", tot_iter); 00940 #endif 00941 00942 if(placer_opts.place_algorithm == NET_TIMING_DRIVEN_PLACE || 00943 placer_opts.place_algorithm == PATH_TIMING_DRIVEN_PLACE || 00944 placer_opts.enable_timing_computations) 00945 { 00946 00947 net_delay = remember_net_delay_original_ptr; 00948 00949 free_placement_structs(placer_opts.place_cost_type, 00950 placer_opts.num_regions, old_region_occ_x, 00951 old_region_occ_y, placer_opts); 00952 free_lookups_and_criticalities(&net_delay, &net_slack); 00953 } 00954 00955 /* placement is done - find mst of all nets. 00956 * creating mst for each net; this gives me an ordering of sinks 00957 * by which I will direct search (A*) for. */ 00958 if(*mst) 00959 { 00960 for(inet = 0; inet < num_nets; inet++) 00961 { 00962 assert((*mst)[inet]); 00963 free((*mst)[inet]); 00964 } 00965 free(*mst); 00966 } 00967 *mst = (t_mst_edge **) my_malloc(sizeof(t_mst_edge *) * num_nets); 00968 for(inet = 0; inet < num_nets; inet++) 00969 { 00970 (*mst)[inet] = get_mst_of_net(inet); 00971 } 00972 free(x_lookup); 00973 }