36 #define MAX_MOVES_BEFORE_RECOMPUTE 50000
41 #define MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY 4
45 #define NOT_UPDATED_YET 'N'
46 #define UPDATED_ONCE 'U'
47 #define GOT_FROM_SCRATCH 'S'
64 #define MAX_INV_TIMING_COST 1.e9
197 static const float cross_count[50] = { 1.0, 1.0, 1.0, 1.0828, 1.1536, 1.2206, 1.2823, 1.3385, 1.3991, 1.4493, 1.4974,
198 1.5455, 1.5937, 1.6418, 1.6899, 1.7304, 1.7709, 1.8114, 1.8519, 1.8924,
199 1.9288, 1.9652, 2.0015, 2.0379, 2.0743, 2.1061, 2.1379, 2.1698, 2.2016,
200 2.2334, 2.2646, 2.2958, 2.3271, 2.3583, 2.3895, 2.4187, 2.4479, 2.4772,
201 2.5064, 2.5356, 2.5610, 2.5864, 2.6117, 2.6371, 2.6625, 2.6887, 2.7148,
202 2.7410, 2.7671, 2.7933 };
206 static void print_clb_placement(
const char *fname);
210 float place_cost_exp,
float ***old_region_occ_x,
217 float **old_region_occ_x,
float **old_region_occ_y,
231 static int try_place_macro(
int itype,
int ichoice,
int imacro,
int * free_locations);
247 float rlim,
float **old_region_occ_x,
248 float **old_region_occ_y,
250 float inverse_prev_bb_cost,
float inverse_prev_timing_cost,
253 static void check_place(
float bb_cost,
float timing_cost,
257 static float starting_t(
float *cost_ptr,
float *bb_cost_ptr,
258 float *timing_cost_ptr,
float **old_region_occ_x,
259 float **old_region_occ_y,
262 float inverse_prev_bb_cost,
float inverse_prev_timing_cost,
263 float *delay_cost_ptr);
265 static void update_t(
float *t,
float std_dev,
float rlim,
float success_rat,
268 static void update_rlim(
float *rlim,
float success_rat);
270 static int exit_crit(
float t,
float cost,
275 static double get_std_dev(
int n,
double sum_x_squared,
double av_x);
285 static void comp_td_costs(
float *timing_cost,
float *connection_delay_sum);
289 static boolean find_to(
int x_from,
int y_from,
t_type_ptr type,
float rlim,
int *x_to,
int *y_to);
294 struct s_bb *bb_edge_new,
int xold,
int yold,
int xnew,
int ynew);
301 struct s_bb *num_on_edges);
321 int tot_iter, inner_iter, success_sum, move_lim, moves_since_cost_recompute, width_fac,
322 num_connections, inet, ipin, outer_crit_iter_count, inner_crit_iter_count,
324 float t, success_rat, rlim, cost, timing_cost, bb_cost, new_bb_cost, new_timing_cost,
325 delay_cost, new_delay_cost, place_delay_value, inverse_prev_bb_cost, inverse_prev_timing_cost,
326 oldt, **old_region_occ_x, **old_region_occ_y, **
net_delay = NULL, crit_exponent,
327 first_rlim, final_rlim, inverse_delta_rlim, critical_path_delay =
UNDEFINED,
328 **remember_net_delay_original_ptr;
329 double av_cost, av_bb_cost, av_timing_cost, av_delay_cost, sum_of_squares, std_dev;
330 int total_swap_attempts;
339 remember_net_delay_original_ptr = NULL;
352 det_routing_arch, segment_inf, timing_inf, &net_delay, directs, num_directs);
354 remember_net_delay_original_ptr =
net_delay;
357 #ifdef PRINT_LOWER_BOUND
371 vpr_printf(TIO_MESSAGE_INFO,
"Lower bound assuming delay of %g\n", place_delay_value);
403 &old_region_occ_x, &old_region_occ_y, placer_opts,
404 directs, num_directs);
422 vpr_printf(TIO_MESSAGE_INFO,
"There are %d point to point connections in this circuit.\n", num_connections);
426 for (inet = 0; inet <
num_nets; inet++)
433 place_delay_value = delay_cost / num_connections;
438 place_delay_value = 0;
459 outer_crit_iter_count = 1;
464 inverse_prev_timing_cost = 1 / timing_cost;
465 inverse_prev_bb_cost = 1 / bb_cost;
473 place_delay_value = 0;
474 outer_crit_iter_count = 0;
478 inverse_prev_timing_cost = 0;
479 inverse_prev_bb_cost = 0;
485 inner_recompute_limit = (int) (0.5
490 inner_recompute_limit = move_lim + 1;
504 inverse_delta_rlim = 1 / (first_rlim - final_rlim);
507 old_region_occ_x, old_region_occ_y,
508 annealing_sched, move_lim, rlim,
510 inverse_prev_bb_cost, inverse_prev_timing_cost, &delay_cost);
512 moves_since_cost_recompute = 0;
513 vpr_printf(TIO_MESSAGE_INFO,
"Initial placement cost: %g bb_cost: %g td_cost: %g delay_cost: %g\n",
514 cost, bb_cost, timing_cost, delay_cost);
518 vpr_printf(TIO_MESSAGE_INFO,
"%9s %9s %11s %11s %11s %11s %8s %8s %7s %7s %7s %9s %7s\n",
519 "---------",
"---------",
"-----------",
"-----------",
"-----------",
"-----------",
520 "--------",
"--------",
"-------",
"-------",
"-------",
"---------",
"-------");
521 vpr_printf(TIO_MESSAGE_INFO,
"%9s %9s %11s %11s %11s %11s %8s %8s %7s %7s %7s %9s %7s\n",
522 "T",
"Cost",
"Av BB Cost",
"Av TD Cost",
"Av Tot Del",
523 "P to P Del",
"d_max",
"Ac Rate",
"Std Dev",
"R limit",
"Exp",
524 "Tot Moves",
"Alpha");
525 vpr_printf(TIO_MESSAGE_INFO,
"%9s %9s %11s %11s %11s %11s %8s %8s %7s %7s %7s %9s %7s\n",
526 "---------",
"---------",
"-----------",
"-----------",
"-----------",
"-----------",
527 "--------",
"--------",
"-------",
"-------",
"-------",
"---------",
"-------");
530 sprintf(msg,
"Initial Placement. Cost: %g BB Cost: %g TD Cost %g Delay Cost: %g \t Channel Factor: %d",
531 cost, bb_cost, timing_cost, delay_cost, width_fac);
534 while (
exit_crit(t, cost, annealing_sched) == 0) {
554 vpr_printf(TIO_MESSAGE_INFO,
"Outer loop recompute criticalities\n");
556 place_delay_value = delay_cost / num_connections;
569 outer_crit_iter_count = 0;
571 outer_crit_iter_count++;
575 inverse_prev_bb_cost = 1 / bb_cost;
580 inner_crit_iter_count = 1;
582 for (inner_iter = 0; inner_iter < move_lim; inner_iter++) {
583 swap_result =
try_swap(t, &cost, &bb_cost, &timing_cost, rlim,
587 inverse_prev_bb_cost, inverse_prev_timing_cost, &delay_cost);
593 av_bb_cost += bb_cost;
594 av_timing_cost += timing_cost;
595 av_delay_cost += delay_cost;
596 sum_of_squares += cost * cost;
598 }
else if (swap_result ==
ABORTED) {
612 if (inner_crit_iter_count >= inner_recompute_limit
613 && inner_iter != move_lim - 1) {
615 inner_crit_iter_count = 0;
617 vpr_printf(TIO_MESSAGE_TRACE,
"Inner loop recompute criticalities\n");
625 place_delay_value = delay_cost / num_connections;
638 inner_crit_iter_count++;
641 vpr_printf(TIO_MESSAGE_TRACE,
"t = %g cost = %g bb_cost = %g timing_cost = %g move = %d dmax = %g\n",
642 t, cost, bb_cost, timing_cost, inner_iter, delay_cost);
653 moves_since_cost_recompute += move_lim;
656 if (fabs(new_bb_cost - bb_cost) > bb_cost *
ERROR_TOL) {
657 vpr_printf(TIO_MESSAGE_ERROR,
"in try_place: new_bb_cost = %g, old bb_cost = %g\n",
658 new_bb_cost, bb_cost);
661 bb_cost = new_bb_cost;
667 if (fabs(new_timing_cost - timing_cost) > timing_cost * ERROR_TOL) {
668 vpr_printf(TIO_MESSAGE_ERROR,
"in try_place: new_timing_cost = %g, old timing_cost = %g\n",
669 new_timing_cost, timing_cost);
672 if (fabs(new_delay_cost - delay_cost) > delay_cost * ERROR_TOL) {
673 vpr_printf(TIO_MESSAGE_ERROR,
"in try_place: new_delay_cost = %g, old delay_cost = %g\n",
674 new_delay_cost, delay_cost);
677 timing_cost = new_timing_cost;
683 moves_since_cost_recompute = 0;
686 tot_iter += move_lim;
687 success_rat = ((float) success_sum) / move_lim;
688 if (success_sum == 0) {
690 av_bb_cost = bb_cost;
691 av_timing_cost = timing_cost;
692 av_delay_cost = delay_cost;
694 av_cost /= success_sum;
695 av_bb_cost /= success_sum;
696 av_timing_cost /= success_sum;
697 av_delay_cost /= success_sum;
699 std_dev =
get_std_dev(success_sum, sum_of_squares, av_cost);
702 update_t(&t, std_dev, rlim, success_rat, annealing_sched);
706 vpr_printf(TIO_MESSAGE_INFO,
"%9.5f %9.5g %11.6g %11.6g %11.6g %11.6g %8.4f %8.4f %7.4f %7.4f %7.4f %9d %7.4f\n",
707 oldt, av_cost, av_bb_cost, av_timing_cost, av_delay_cost, place_delay_value,
708 critical_path_delay, success_rat, std_dev, rlim, crit_exponent, tot_iter, t / oldt);
711 sprintf(msg,
"Cost: %g BB Cost %g TD Cost %g Temperature: %g",
712 cost, bb_cost, timing_cost, t);
718 crit_exponent = (1 - (rlim - final_rlim) * inverse_delta_rlim)
725 print_clb_placement(
"first_iteration_clb_placement.echo");
746 vpr_printf(TIO_MESSAGE_INFO,
"Outer loop recompute criticalities\n");
748 place_delay_value = delay_cost / num_connections;
759 outer_crit_iter_count = 0;
761 outer_crit_iter_count++;
763 inverse_prev_bb_cost = 1 / (bb_cost);
768 inner_crit_iter_count = 1;
770 for (inner_iter = 0; inner_iter < move_lim; inner_iter++) {
771 swap_result =
try_swap(t, &cost, &bb_cost, &timing_cost, rlim,
772 old_region_occ_x, old_region_occ_y,
774 inverse_prev_bb_cost, inverse_prev_timing_cost, &delay_cost);
779 av_bb_cost += bb_cost;
780 av_delay_cost += delay_cost;
781 av_timing_cost += timing_cost;
782 sum_of_squares += cost * cost;
788 if (inner_crit_iter_count >= inner_recompute_limit
789 && inner_iter != move_lim - 1) {
791 inner_crit_iter_count = 0;
793 vpr_printf(TIO_MESSAGE_TRACE,
"Inner loop recompute criticalities\n");
797 place_delay_value = delay_cost / num_connections;
807 inner_crit_iter_count++;
810 }
else if (swap_result ==
ABORTED) {
817 vpr_printf(TIO_MESSAGE_INFO,
"t = %g, cost = %g, move = %d\n", t, cost, tot_iter);
820 tot_iter += move_lim;
821 success_rat = ((float) success_sum) / move_lim;
822 if (success_sum == 0) {
824 av_bb_cost = bb_cost;
825 av_delay_cost = delay_cost;
826 av_timing_cost = timing_cost;
828 av_cost /= success_sum;
829 av_bb_cost /= success_sum;
830 av_delay_cost /= success_sum;
831 av_timing_cost /= success_sum;
834 std_dev =
get_std_dev(success_sum, sum_of_squares, av_cost);
837 vpr_printf(TIO_MESSAGE_INFO,
"%9.5f %9.5g %11.6g %11.6g %11.6g %11.6g %8s %8.4f %7.4f %7.4f %7.4f %9d\n",
838 t, av_cost, av_bb_cost, av_timing_cost, av_delay_cost, place_delay_value,
839 " ", success_rat, std_dev, rlim, crit_exponent, tot_iter);
861 for (inet = 0; inet <
num_nets; inet++)
892 vpr_printf(TIO_MESSAGE_INFO,
"Placement estimated critical path delay: %g ns\n", critical_path_delay);
895 sprintf(msg,
"Placement. Cost: %g bb_cost: %g td_cost: %g Channel Factor: %d",
896 cost, bb_cost, timing_cost, width_fac);
897 vpr_printf(TIO_MESSAGE_INFO,
"Placement cost: %g, bb_cost: %g, td_cost: %g, delay_cost: %g\n",
898 cost, bb_cost, timing_cost, delay_cost);
905 abort_rate = num_swap_aborted / total_swap_attempts;
906 vpr_printf(TIO_MESSAGE_INFO,
"Placement total # of swap attempts: %d\n", total_swap_attempts);
907 vpr_printf(TIO_MESSAGE_INFO,
"\tSwap reject rate: %g\n", reject_rate);
908 vpr_printf(TIO_MESSAGE_INFO,
"\tSwap accept rate: %g\n", accept_rate);
909 vpr_printf(TIO_MESSAGE_INFO,
"\tSwap abort rate: %g\n", abort_rate);
913 vpr_printf(TIO_MESSAGE_INFO,
"Total moves attempted: %d.0\n", tot_iter);
917 old_region_occ_x, old_region_occ_y,
923 net_delay = remember_net_delay_original_ptr;
937 for (inet = 0; inet <
num_nets; inet++) {
947 static double get_std_dev(
int n,
double sum_x_squared,
double av_x) {
959 std_dev = (sum_x_squared - n * av_x * av_x) / (
double) (n - 1);
962 std_dev = sqrt(std_dev);
976 *rlim = (*rlim) * (1. - 0.44 + success_rat);
983 static void update_t(
float *t,
float std_dev,
float rlim,
float success_rat,
989 *t = annealing_sched.
alpha_t * (*t);
997 else if (std_dev == 0.)
1003 fac = exp(-LAMBDA * (*t) / std_dev);
1004 fac =
max(0.5, fac);
1011 if (success_rat > 0.96) {
1013 }
else if (success_rat > 0.8) {
1015 }
else if (success_rat > 0.15 || rlim > 1.) {
1029 if (t < annealing_sched.
exit_t) {
1046 float *timing_cost_ptr,
float **old_region_occ_x,
1047 float **old_region_occ_y,
1050 float inverse_prev_bb_cost,
float inverse_prev_timing_cost,
1051 float *delay_cost_ptr) {
1056 double std_dev, av, sum_of_squares;
1059 return (annealing_sched.
init_t);
1065 sum_of_squares = 0.;
1069 for (i = 0; i < move_lim; i++) {
1071 old_region_occ_x, old_region_occ_y,
1072 place_algorithm, timing_tradeoff,
1073 inverse_prev_bb_cost, inverse_prev_timing_cost, delay_cost_ptr);
1078 sum_of_squares += *cost_ptr * (*cost_ptr);
1080 }
else if (swap_result ==
ABORTED) {
1087 if (num_accepted != 0)
1092 std_dev =
get_std_dev(num_accepted, sum_of_squares, av);
1095 if (num_accepted != move_lim) {
1096 vpr_printf(TIO_MESSAGE_WARNING,
"Starting t: %d of %d configurations accepted.\n", num_accepted, move_lim);
1101 vpr_printf(TIO_MESSAGE_INFO,
"std_dev: %g, average cost: %g, starting temp: %g\n", std_dev, av, 20. * std_dev);
1106 return (20. * std_dev);
1115 int imoved_blk, imacro;
1116 int x_from, y_from, z_from, b_to;
1117 int abort_swap =
FALSE;
1119 x_from =
block[b_from].
x;
1120 y_from =
block[b_from].
y;
1121 z_from =
block[b_from].
z;
1126 if (b_to ==
EMPTY) {
1151 return (abort_swap);
1188 return (abort_swap);
1197 int imacro, imember;
1198 int x_swap_offset, y_swap_offset, z_swap_offset, x_from, y_from, z_from, b_to;
1199 int curr_b_from, curr_x_from, curr_y_from, curr_z_from, curr_b_to, curr_x_to, curr_y_to, curr_z_to;
1200 int abort_swap =
FALSE;
1202 x_from =
block[b_from].
x;
1203 y_from =
block[b_from].
y;
1204 z_from =
block[b_from].
z;
1209 if ( imacro != -1) {
1213 x_swap_offset = x_to - x_from;
1214 y_swap_offset = y_to - y_from;
1215 z_swap_offset = z_to - z_from;
1217 for (imember = 0; imember < pl_macros[imacro].
num_blocks && abort_swap ==
FALSE; imember++) {
1223 curr_x_from =
block[curr_b_from].
x;
1224 curr_y_from =
block[curr_b_from].
y;
1225 curr_z_from =
block[curr_b_from].
z;
1227 curr_x_to = curr_x_from + x_swap_offset;
1228 curr_y_to = curr_y_from + y_swap_offset;
1229 curr_z_to = curr_z_from + z_swap_offset;
1232 if (curr_x_to < 1 || curr_x_to >
nx || curr_y_to < 1 || curr_y_to >
ny || curr_z_to < 0) {
1235 curr_b_to =
grid[curr_x_to][curr_y_to].
blocks[curr_z_to];
1248 return (abort_swap);
1253 float rlim,
float **old_region_occ_x,
1254 float **old_region_occ_y,
1256 float inverse_prev_bb_cost,
float inverse_prev_timing_cost,
1257 float *delay_cost) {
1266 int b_from, x_from, y_from, z_from, x_to, y_to, z_to;
1267 int num_nets_affected;
1268 float delta_c, bb_delta_c, timing_delta_c, delay_delta_c;
1269 int inet, iblk, bnum, iblk_pin, inet_affected;
1270 int abort_swap =
FALSE;
1280 delay_delta_c = 0.0;
1295 x_from =
block[b_from].
x;
1296 y_from =
block[b_from].
y;
1297 z_from =
block[b_from].
z;
1299 if (!
find_to(x_from, y_from,
block[b_from].type, rlim, &x_to,
1304 if (
grid[x_to][y_to].type->capacity > 1) {
1324 if (abort_swap ==
FALSE) {
1351 &ts_bb_edge_new[inet],
1362 for (inet_affected = 0; inet_affected < num_nets_affected; inet_affected++) {
1377 delta_c = (1 - timing_tradeoff) * bb_delta_c * inverse_prev_bb_cost
1378 + timing_tradeoff * timing_delta_c * inverse_prev_timing_cost;
1380 delta_c = bb_delta_c;
1387 *cost = *cost + delta_c;
1388 *bb_cost = *bb_cost + bb_delta_c;
1394 *timing_cost = *timing_cost + timing_delta_c;
1395 *delay_cost = *delay_cost + delay_delta_c;
1401 for (inet_affected = 0; inet_affected < num_nets_affected; inet_affected++) {
1404 bb_coords[inet] = ts_bb_coord_new[inet];
1442 for (inet_affected = 0; inet_affected < num_nets_affected; inet_affected++) {
1463 return (keep_switch);
1487 int iblk, iblk_pin, inet, bnum, num_affected_nets;
1489 num_affected_nets = 0;
1509 nets_to_update[num_affected_nets] = inet;
1510 num_affected_nets++;
1517 return num_affected_nets;
1527 int x_rel, y_rel, rlx, rly, min_x, max_x, min_y, max_y;
1531 int block_index, ipos;
1533 assert(type ==
grid[x_from][y_from].type);
1537 active_area = 4 * rlx * rly;
1545 if (rlx < 1 || rlx >
nx + 1) {
1546 vpr_printf(TIO_MESSAGE_ERROR,
"in find_to: rlx = %d\n", rlx);
1552 block_index = type->index;
1568 *x_to = legal_pos[block_index][ipos].
x;
1569 *y_to = legal_pos[block_index][ipos].
y;
1572 *x_to = min_x + x_rel;
1574 *y_to = min_y + y_rel;
1578 if((x_from == *x_to) && (y_from == *y_to)) {
1580 }
else if(*x_to > max_x || *x_to < min_x || *y_to > max_y || *y_to < min_y) {
1582 }
else if(
grid[*x_to][*y_to].type !=
grid[x_from][y_from].type) {
1586 assert(*x_to >= 0 && *x_to <=
nx + 1);
1587 assert(*y_to >= 0 && *y_to <=
ny + 1);
1588 }
while (is_legal ==
FALSE);
1591 if (*x_to < 0 || *x_to >
nx + 1 || *y_to < 0 || *y_to >
ny + 1) {
1592 vpr_printf(TIO_MESSAGE_ERROR,
"in routine find_to: (x_to,y_to) = (%d,%d)\n", *x_to, *y_to);
1596 assert(type ==
grid[*x_to][*y_to].type);
1605 float prob_fac, fnum;
1621 prob_fac = exp(-delta_c / t);
1622 if (prob_fac > fnum) {
1641 for (inet = 0; inet <
num_nets; inet++) {
1656 int source_block, sink_block;
1657 int delta_x, delta_y;
1659 float delay_source_to_sink;
1661 delay_source_to_sink = 0.;
1669 assert(source_type != NULL);
1670 assert(sink_type != NULL);
1672 delta_x = abs(
block[sink_block].x -
block[source_block].x);
1673 delta_y = abs(
block[sink_block].y -
block[source_block].y);
1690 if (delay_source_to_sink < 0) {
1691 vpr_printf(TIO_MESSAGE_ERROR,
"in comp_td_point_to_point_delay: Bad delay_source_to_sink value delta(%d, %d) delay of %g\n", delta_x, delta_y, delay_source_to_sink);
1692 vpr_printf(TIO_MESSAGE_ERROR,
"in comp_td_point_to_point_delay: Delay is less than 0\n");
1696 return (delay_source_to_sink);
1703 int iblk_pin, net_pin, inet, ipin;
1704 int iblk, iblk2, bnum, driven_by_moved_block;
1724 driven_by_moved_block =
FALSE;
1727 driven_by_moved_block =
TRUE;
1731 if (driven_by_moved_block ==
FALSE) {
1761 int inet, net_pin, ipin;
1762 float delta_timing_cost, delta_delay_cost, temp_delay;
1763 int iblk, iblk2, bnum, iblk_pin, driven_by_moved_block;
1765 delta_timing_cost = 0.;
1766 delta_delay_cost = 0.;
1790 driven_by_moved_block =
FALSE;
1793 driven_by_moved_block =
TRUE;
1796 if (driven_by_moved_block ==
FALSE) {
1825 *delta_timing = delta_timing_cost;
1826 *delta_delay = delta_delay_cost;
1835 float loc_timing_cost, loc_connection_delay_sum, temp_delay_cost,
1838 loc_timing_cost = 0.;
1839 loc_connection_delay_sum = 0.;
1841 for (inet = 0; inet <
num_nets; inet++) {
1849 loc_connection_delay_sum += temp_delay_cost;
1855 loc_timing_cost += temp_timing_cost;
1861 *timing_cost = loc_timing_cost;
1863 *connection_delay_sum = loc_connection_delay_sum;
1879 double expected_wirelength;
1882 expected_wirelength = 0.0;
1884 for (inet = 0; inet <
num_nets; inet++) {
1900 if (method ==
CHECK)
1906 if (method ==
CHECK) {
1908 vpr_printf(TIO_MESSAGE_INFO,
"BB estimate of min-dist (placement) wirelength: %.0f\n", expected_wirelength);
1914 float **old_region_occ_x,
float **old_region_occ_y,
1928 for (inet = 0; inet <
num_nets; inet++) {
1960 free(pl_macros[imacro].members);
1976 float place_cost_exp,
float ***old_region_occ_x,
1977 float ***old_region_occ_y,
struct s_placer_opts placer_opts,
1983 int inet, ipin, max_pins_per_clb, i;
1988 max_pins_per_clb = 0;
2008 for (inet = 0; inet <
num_nets; inet++) {
2013 clb_net[inet].num_sinks *
sizeof(
float));
2017 clb_net[inet].num_sinks *
sizeof(
float));
2021 clb_net[inet].num_sinks *
sizeof(
float));
2025 clb_net[inet].num_sinks *
sizeof(
float));
2028 for (inet = 0; inet <
num_nets; inet++) {
2044 for (inet = 0; inet <
num_nets; inet++){
2053 *old_region_occ_x = NULL;
2054 *old_region_occ_y = NULL;
2082 struct s_bb *num_on_edges) {
2090 int xmin_edge, xmax_edge, ymin_edge, ymax_edge;
2113 for (ipin = 1; ipin < n_pins; ipin++) {
2134 }
else if (x < xmin) {
2137 }
else if (x > xmax) {
2147 }
else if (y < ymin) {
2150 }
else if (y > ymax) {
2163 num_on_edges->
xmin = xmin_edge;
2164 num_on_edges->
xmax = xmax_edge;
2165 num_on_edges->
ymin = ymin_edge;
2166 num_on_edges->
ymax = ymax_edge;
2174 double ncost, crossing;
2179 if (((
clb_net[inet].num_sinks + 1) > 50)
2180 && ((
clb_net[inet].num_sinks + 1) < 85)) {
2182 }
else if ((
clb_net[inet].num_sinks + 1) >= 85) {
2184 - 0.0000018 * (
clb_net[inet].num_sinks + 1)
2197 ncost = (bbptr->
xmax - bbptr->
xmin + 1) * crossing;
2199 ncost += (bbptr->
ymax - bbptr->
ymin + 1) * crossing;
2209 float ncost, crossing;
2214 if ((
clb_net[inet].num_sinks + 1) > 50) {
2228 ncost = (bbptr->
xmax - bbptr->
xmin + 1) * crossing
2231 ncost += (bbptr->
ymax - bbptr->
ymin + 1) * crossing
2268 }
else if (x > xmax) {
2274 }
else if (y > ymax) {
2293 struct s_bb *bb_edge_new,
int xold,
int yold,
int xnew,
int ynew) {
2308 struct s_bb *curr_bb_edge, *curr_bb_coord;
2322 curr_bb_coord = &bb_coords[inet];
2328 curr_bb_coord = bb_coord_new;
2329 curr_bb_edge = bb_edge_new;
2338 if (xold == curr_bb_coord->
xmax) {
2339 if (curr_bb_edge->
xmax == 1) {
2344 bb_edge_new->
xmax = curr_bb_edge->
xmax - 1;
2345 bb_coord_new->
xmax = curr_bb_coord->
xmax;
2350 bb_coord_new->
xmax = curr_bb_coord->
xmax;
2351 bb_edge_new->
xmax = curr_bb_edge->
xmax;
2356 if (xnew < curr_bb_coord->
xmin) {
2357 bb_coord_new->
xmin = xnew;
2358 bb_edge_new->
xmin = 1;
2361 else if (xnew == curr_bb_coord->
xmin) {
2362 bb_coord_new->
xmin = xnew;
2363 bb_edge_new->
xmin = curr_bb_edge->
xmin + 1;
2367 bb_coord_new->
xmin = curr_bb_coord->
xmin;
2368 bb_edge_new->
xmin = curr_bb_edge->
xmin;
2373 else if (xnew > xold) {
2377 if (xold == curr_bb_coord->
xmin) {
2378 if (curr_bb_edge->
xmin == 1) {
2383 bb_edge_new->
xmin = curr_bb_edge->
xmin - 1;
2384 bb_coord_new->
xmin = curr_bb_coord->
xmin;
2389 bb_coord_new->
xmin = curr_bb_coord->
xmin;
2390 bb_edge_new->
xmin = curr_bb_edge->
xmin;
2395 if (xnew > curr_bb_coord->
xmax) {
2396 bb_coord_new->
xmax = xnew;
2397 bb_edge_new->
xmax = 1;
2400 else if (xnew == curr_bb_coord->
xmax) {
2401 bb_coord_new->
xmax = xnew;
2402 bb_edge_new->
xmax = curr_bb_edge->
xmax + 1;
2406 bb_coord_new->
xmax = curr_bb_coord->
xmax;
2407 bb_edge_new->
xmax = curr_bb_edge->
xmax;
2412 bb_coord_new->
xmin = curr_bb_coord->
xmin;
2413 bb_coord_new->
xmax = curr_bb_coord->
xmax;
2414 bb_edge_new->
xmin = curr_bb_edge->
xmin;
2415 bb_edge_new->
xmax = curr_bb_edge->
xmax;
2424 if (yold == curr_bb_coord->
ymax) {
2425 if (curr_bb_edge->
ymax == 1) {
2430 bb_edge_new->
ymax = curr_bb_edge->
ymax - 1;
2431 bb_coord_new->
ymax = curr_bb_coord->
ymax;
2436 bb_coord_new->
ymax = curr_bb_coord->
ymax;
2437 bb_edge_new->
ymax = curr_bb_edge->
ymax;
2442 if (ynew < curr_bb_coord->
ymin) {
2443 bb_coord_new->
ymin = ynew;
2444 bb_edge_new->
ymin = 1;
2447 else if (ynew == curr_bb_coord->
ymin) {
2448 bb_coord_new->
ymin = ynew;
2449 bb_edge_new->
ymin = curr_bb_edge->
ymin + 1;
2453 bb_coord_new->
ymin = curr_bb_coord->
ymin;
2454 bb_edge_new->
ymin = curr_bb_edge->
ymin;
2458 else if (ynew > yold) {
2462 if (yold == curr_bb_coord->
ymin) {
2463 if (curr_bb_edge->
ymin == 1) {
2468 bb_edge_new->
ymin = curr_bb_edge->
ymin - 1;
2469 bb_coord_new->
ymin = curr_bb_coord->
ymin;
2474 bb_coord_new->
ymin = curr_bb_coord->
ymin;
2475 bb_edge_new->
ymin = curr_bb_edge->
ymin;
2480 if (ynew > curr_bb_coord->
ymax) {
2481 bb_coord_new->
ymax = ynew;
2482 bb_edge_new->
ymax = 1;
2485 else if (ynew == curr_bb_coord->
ymax) {
2486 bb_coord_new->
ymax = ynew;
2487 bb_edge_new->
ymax = curr_bb_edge->
ymax + 1;
2491 bb_coord_new->
ymax = curr_bb_coord->
ymax;
2492 bb_edge_new->
ymax = curr_bb_edge->
ymax;
2497 bb_coord_new->
ymin = curr_bb_coord->
ymin;
2498 bb_coord_new->
ymax = curr_bb_coord->
ymax;
2499 bb_edge_new->
ymin = curr_bb_edge->
ymin;
2500 bb_edge_new->
ymax = curr_bb_edge->
ymax;
2515 for (i = 0; i <=
nx + 1; i++) {
2516 for (j = 0; j <=
ny + 1; j++) {
2520 if (
grid[i][j].offset == 0) {
2538 for (i = 0; i <=
nx + 1; i++) {
2539 for (j = 0; j <=
ny + 1; j++) {
2541 if (
grid[i][j].offset == 0) {
2543 legal_pos[itype][index[itype]].
x = i;
2544 legal_pos[itype][index[itype]].
y = j;
2545 legal_pos[itype][index[itype]].
z = k;
2568 int member_x, member_y, member_z;
2571 int macro_can_be_placed =
TRUE;
2574 for (imember = 0; imember < pl_macros[imacro].
num_blocks; imember++) {
2583 if (member_x <=
nx+1 && member_y <=
ny+1
2584 &&
grid[member_x][member_y].type->index == itype
2590 macro_can_be_placed =
FALSE;
2595 return (macro_can_be_placed);
2601 int x, y, z, member_x, member_y, member_z, imember;
2603 int macro_placed =
FALSE;
2606 x = legal_pos[itype][ichoice].
x;
2607 y = legal_pos[itype][ichoice].
y;
2608 z = legal_pos[itype][ichoice].
z;
2611 if (
grid[x][y].blocks[z] !=
OPEN) {
2612 return (macro_placed);
2617 if (macro_can_be_placed ==
TRUE) {
2620 macro_placed =
TRUE;
2621 for (imember = 0; imember < pl_macros[imacro].
num_blocks; imember++) {
2642 return (macro_placed);
2650 int imacro, iblk, itype, itry, ichoice;
2656 macro_placed =
FALSE;
2661 if (free_locations[itype] < pl_macros[imacro].
num_blocks) {
2662 vpr_printf (TIO_MESSAGE_ERROR,
"Initial placement failed.\n");
2663 vpr_printf (TIO_MESSAGE_ERROR,
"Could not place macro length %d with head block %s (#%d); not enough free locations of type %s (#%d).\n",
2665 vpr_printf (TIO_MESSAGE_INFO,
"VPR cannot auto-size for your circuit, please resize the FPGA manually.\n");
2670 for (itry = 0; itry < macros_max_num_tries && macro_placed ==
FALSE; itry++) {
2673 ichoice =
my_irand(free_locations[itype] - 1);
2676 macro_placed =
try_place_macro(itype, ichoice, imacro, free_locations);
2681 if (macro_placed ==
FALSE){
2689 for (ichoice = 0; ichoice < free_locations[itype] && macro_placed ==
FALSE; ichoice++) {
2692 macro_placed =
try_place_macro(itype, ichoice, imacro, free_locations);
2697 if (macro_placed ==
FALSE) {
2699 vpr_printf (TIO_MESSAGE_ERROR,
"Initial placement failed.\n");
2700 vpr_printf (TIO_MESSAGE_ERROR,
"Could not place macro length %d with head block %s (#%d); not enough free locations of type %s (#%d).\n",
2702 vpr_printf (TIO_MESSAGE_INFO,
"Please manually size the FPGA because VPR can't do this yet.\n");
2720 int ichoice, x, y, z;
2724 if (
block[iblk].x != -1) {
2738 if (free_locations[itype] <= 0) {
2739 vpr_printf (TIO_MESSAGE_ERROR,
"Initial placement failed.\n");
2740 vpr_printf (TIO_MESSAGE_ERROR,
"Could not place block %s (#%d); no free locations of type %s (#%d).\n",
2745 ichoice =
my_irand(free_locations[itype] - 1);
2746 x = legal_pos[itype][ichoice].
x;
2747 y = legal_pos[itype][ichoice].
y;
2748 z = legal_pos[itype][ichoice].
z;
2751 assert (
grid[x][y].blocks[z] ==
OPEN);
2765 legal_pos[itype][ichoice] = legal_pos[itype][free_locations[itype] - 1];
2766 free_locations[itype]--;
2773 char *pad_loc_file) {
2780 int i, j, k, iblk, itype, x, y, z, ichoice;
2781 int *free_locations;
2788 for (itype = 0; itype <
num_types; itype++) {
2795 for (i = 0; i <=
nx + 1; i++) {
2796 for (j = 0; j <=
ny + 1; j++) {
2815 for (itype = 0; itype <
num_types; itype++) {
2816 assert (free_locations[itype] >= 0);
2817 for (ichoice = 0; ichoice < free_locations[itype]; ichoice++) {
2818 x = legal_pos[itype][ichoice].
x;
2819 y = legal_pos[itype][ichoice].
y;
2820 z = legal_pos[itype][ichoice].
z;
2823 if (
grid[x][y].blocks[z] !=
OPEN) {
2824 legal_pos[itype][ichoice] = legal_pos[itype][free_locations[itype] - 1];
2825 free_locations[itype]--;
2836 if (pad_loc_type ==
USER) {
2844 vpr_printf(TIO_MESSAGE_INFO,
"At end of initial_placement.\n");
2849 free(free_locations);
2855 for (i = 0; i <=
ny; i++)
2860 for (i = 0; i <=
nx; i++)
2887 for (i = 0; i <=
ny; i++)
2891 for (i = 0; i <=
nx; i++)
2899 for (high = 1; high <=
ny; high++) {
2901 for (low = 0; low < high; low++) {
2915 for (high = 0; high <=
ny; high++)
2916 for (low = 0; low <= high; low++) {
2921 (
double) place_cost_exp);
2929 for (high = 1; high <=
nx; high++) {
2931 for (low = 0; low < high; low++) {
2940 for (high = 0; high <=
nx; high++)
2941 for (low = 0; low <= high; low++) {
2946 (
double) place_cost_exp);
2961 int i, j, k, error = 0, bnum;
2962 float bb_cost_check;
2964 float timing_cost_check, delay_cost_check;
2965 int imacro, imember, head_iblk, member_iblk, member_x, member_y, member_z;
2968 vpr_printf(TIO_MESSAGE_INFO,
"bb_cost recomputed from scratch: %g\n", bb_cost_check);
2969 if (fabs(bb_cost_check - bb_cost) > bb_cost *
ERROR_TOL) {
2970 vpr_printf(TIO_MESSAGE_ERROR,
"bb_cost_check: %g and bb_cost: %g differ in check_place.\n", bb_cost_check, bb_cost);
2977 vpr_printf(TIO_MESSAGE_INFO,
"timing_cost recomputed from scratch: %g\n", timing_cost_check);
2978 if (fabs(timing_cost_check - timing_cost) > timing_cost * ERROR_TOL) {
2979 vpr_printf(TIO_MESSAGE_ERROR,
"timing_cost_check: %g and timing_cost: %g differ in check_place.\n",
2980 timing_cost_check, timing_cost);
2983 vpr_printf(TIO_MESSAGE_INFO,
"delay_cost recomputed from scratch: %g\n", delay_cost_check);
2984 if (fabs(delay_cost_check - delay_cost) > delay_cost * ERROR_TOL) {
2985 vpr_printf(TIO_MESSAGE_ERROR,
"delay_cost_check: %g and delay_cost: %g differ in check_place.\n",
2986 delay_cost_check, delay_cost);
2996 for (i = 0; i <= (
nx + 1); i++)
2997 for (j = 0; j <= (
ny + 1); j++) {
2998 if (
grid[i][j].usage >
grid[i][j].type->capacity) {
2999 vpr_printf(TIO_MESSAGE_ERROR,
"Block at grid location (%d,%d) overused. Usage is %d.\n",
3000 i, j,
grid[i][j].usage);
3009 if (
block[bnum].type !=
grid[i][j].type) {
3010 vpr_printf(TIO_MESSAGE_ERROR,
"Block %d type does not match grid location (%d,%d) type.\n",
3014 if ((
block[bnum].x != i) || (
block[bnum].y != j)) {
3015 vpr_printf(TIO_MESSAGE_ERROR,
"Block %d location conflicts with grid(%d,%d) data.\n",
3022 if (usage_check !=
grid[i][j].usage) {
3023 vpr_printf(TIO_MESSAGE_ERROR,
"Location (%d,%d) usage is %d, but has actual usage %d.\n",
3024 i, j,
grid[i][j].usage, usage_check);
3031 if (bdone[i] != 1) {
3032 vpr_printf(TIO_MESSAGE_ERROR,
"Block %d listed %d times in data structures.\n",
3043 for (imember = 0; imember < pl_macros[imacro].
num_blocks; imember++) {
3053 if (
block[member_iblk].x != member_x
3054 ||
block[member_iblk].y != member_y
3055 ||
block[member_iblk].z != member_z) {
3056 vpr_printf(TIO_MESSAGE_ERROR,
"Block %d in pl_macro #%d is not placed in the proper orientation.\n",
3057 member_iblk, imacro);
3062 if (
grid[member_x][member_y].blocks[member_z] != member_iblk) {
3063 vpr_printf(TIO_MESSAGE_ERROR,
"Block %d in pl_macro #%d is not placed in the proper orientation.\n",
3064 member_iblk, imacro);
3072 vpr_printf(TIO_MESSAGE_INFO,
"Completed placement consistency check successfully.\n");
3076 #ifdef PRINT_REL_POS_DISTR
3077 print_relative_pos_distr(
void);
3081 vpr_printf(TIO_MESSAGE_ERROR,
"Completed placement consistency check, %d errors found.\n", error);
3082 vpr_printf(TIO_MESSAGE_INFO,
"Aborting program.\n");
3089 static void print_clb_placement(
const char *fname) {
3097 fprintf(fp,
"Complex block placements:\n\n");
3099 fprintf(fp,
"Block #\tName\t(X, Y, Z).\n");
3109 if(ts_bb_coord_new != NULL) {
3110 free(ts_bb_coord_new);
3111 free(ts_bb_edge_new);
3116 ts_bb_coord_new = NULL;
3117 ts_bb_edge_new = NULL;
static float comp_bb_cost(enum cost_methods method)
#define MAX_MOVES_BEFORE_RECOMPUTE
static void load_legal_placements()
static void free_try_swap_arrays(void)
static float ** chany_place_cost_fac
static int find_affected_nets(int *nets_to_update)
void update_screen(int priority, char *msg, enum pic_type pic_on_screen_val, boolean crit_path_button_enabled)
FILE * my_fopen(const char *fname, const char *flag, int prompt)
static int num_swap_aborted
static struct s_bb * ts_bb_edge_new
static void check_place(float bb_cost, float timing_cost, enum e_place_algorithm place_algorithm, float delay_cost)
void free_port_pin_from_blk_pin(void)
void get_imacro_from_iblk(int *imacro, int iblk, t_pl_macro *macros, int num_macros)
struct s_pl_blocks_to_be_moved t_pl_blocks_to_be_moved
boolean enable_timing_computations
static void comp_delta_td_cost(float *delta_timing, float *delta_delay)
static void get_bb_from_scratch(int inet, struct s_bb *coords, struct s_bb *num_on_edges)
void free_matrix(void *vptr, int nrmin, int nrmax, int ncmin, size_t elsize)
static void initial_placement(enum e_pad_loc_type pad_loc_type, char *pad_loc_file)
static t_legal_pos ** legal_pos
float get_critical_path_delay(void)
enum e_pad_loc_type pad_loc_type
float ** timing_place_crit
static float ** net_delay
static float recompute_bb_cost(void)
float ** delta_clb_to_clb
void free_lookups_and_criticalities(float ***net_delay, t_slack *slacks)
static enum swap_result assess_swap(float delta_c, float t)
static struct s_bb * ts_bb_coord_new
void * my_calloc(size_t nelem, size_t size)
static void alloc_legal_placements()
static void initial_placement_blocks(int *free_locations, enum e_pad_loc_type pad_loc_type)
static double get_std_dev(int n, double sum_x_squared, double av_x)
static void alloc_and_load_try_swap_structs()
void print_critical_path(const char *fname)
void do_timing_analysis(t_slack *slacks, boolean is_prepacked, boolean do_lut_input_balancing, boolean is_final_analysis)
static float comp_td_point_to_point_delay(int inet, int ipin)
#define MAX_NUM_TRIES_TO_PLACE_MACROS_RANDOMLY
static float starting_t(float *cost_ptr, float *bb_cost_ptr, float *timing_cost_ptr, float **old_region_occ_x, float **old_region_occ_y, struct s_annealing_sched annealing_sched, int max_moves, float rlim, enum e_place_algorithm place_algorithm, float timing_tradeoff, float inverse_prev_bb_cost, float inverse_prev_timing_cost, float *delay_cost_ptr)
static enum swap_result try_swap(float t, float *cost, float *bb_cost, float *timing_cost, float rlim, float **old_region_occ_x, float **old_region_occ_y, enum e_place_algorithm place_algorithm, float timing_tradeoff, float inverse_prev_bb_cost, float inverse_prev_timing_cost, float *delay_cost)
boolean getEchoEnabled(void)
t_pl_macro_member * members
static boolean find_to(int x_from, int y_from, t_type_ptr type, float rlim, int *x_to, int *y_to)
static char * bb_updated_before
static void free_fast_cost_update(void)
static t_pl_blocks_to_be_moved blocks_affected
static void comp_td_costs(float *timing_cost, float *connection_delay_sum)
static int * ts_nets_to_update
static int num_swap_accepted
static float get_net_cost(int inet, struct s_bb *bb_ptr)
void init_draw_coords(float width_val)
static float ** chanx_place_cost_fac
#define HUGE_POSITIVE_FLOAT
static float ** temp_point_to_point_delay_cost
void load_criticalities(t_slack *slacks, float crit_exponent)
static int * num_legal_pos
static void * my_malloc(int ibytes)
static int check_macro_can_be_placed(int imacro, int itype, int x, int y, int z)
#define MAX_INV_TIMING_COST
void free_placement_macros_structs(void)
static struct s_bb * bb_num_on_edges
static void update_td_cost(void)
void init_chan(int cfactor, t_chan_width_dist chan_width_dist)
int ** alloc_and_load_net_pin_index()
static void free_placement_structs(float **old_region_occ_x, float **old_region_occ_y, struct s_placer_opts placer_opts)
struct s_pl_moved_block t_pl_moved_block
static int num_swap_rejected
void read_user_pad_loc(char *pad_loc_file)
boolean isEchoFileEnabled(enum e_echo_files echo_option)
static float ** point_to_point_delay_cost
void print_sink_delays(const char *fname)
static int find_affected_blocks(int b_from, int x_to, int y_to, int z_to)
void free_blk_pin_from_port_pin(void)
static float ** temp_point_to_point_timing_cost
static int try_place_macro(int itype, int ichoice, int imacro, int *free_locations)
static void update_rlim(float *rlim, float success_rat)
struct s_grid_tile ** grid
static void alloc_and_load_placement_structs(float place_cost_exp, float ***old_region_occ_x, float ***old_region_occ_y, struct s_placer_opts placer_opts, t_direct_inf *directs, int num_directs)
static void update_bb(int inet, struct s_bb *bb_coord_new, struct s_bb *bb_edge_new, int xold, int yold, int xnew, int ynew)
static void free_legal_placements()
static int count_connections(void)
enum e_place_algorithm place_algorithm
void print_criticality(t_slack *slacks, boolean criticality_is_normalized, const char *fname)
static float * temp_net_cost
void load_constant_net_delay(float **net_delay, float delay_value, struct s_net *nets, int n_nets)
static int exit_crit(float t, float cost, struct s_annealing_sched annealing_sched)
t_slack * alloc_lookups_and_criticalities(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, float ***net_delay, INP t_direct_inf *directs, INP int num_directs)
static void alloc_and_load_for_fast_cost_update(float place_cost_exp)
void print_slack(float **slack, boolean slack_is_normalized, const char *fname)
static const float cross_count[50]
static float ** point_to_point_timing_cost
void print_timing_graph(const char *fname)
int inner_loop_recompute_divider
struct s_type_descriptor * type_descriptors
char * getEchoFileName(enum e_echo_files echo_option)
t_pl_moved_block * moved_blocks
struct s_legal_pos t_legal_pos
static struct s_bb * bb_coords
static t_pl_macro * pl_macros
static int setup_blocks_affected(int b_from, int x_to, int y_to, int z_to)
static int ** net_pin_index
static void initial_placement_pl_macros(int macros_max_num_tries, int *free_locations)
static void get_non_updateable_bb(int inet, struct s_bb *bb_coord_new)
static void update_t(float *t, float std_dev, float rlim, float success_rat, struct s_annealing_sched annealing_sched)
void load_timing_graph_net_delays(float **net_delay)
int alloc_and_load_placement_macros(t_direct_inf *directs, int num_directs, t_pl_macro **macros)
static double get_net_wirelength_estimate(int inet, struct s_bb *bbptr)
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_direct_inf *directs, int num_directs)