00001 #include <stdio.h>
00002 #include <math.h>
00003 #include <string.h>
00004 #include "util.h"
00005 #include "vpr_types.h"
00006 #include "globals.h"
00007 #include "route_common.h"
00008 #include "place_and_route.h"
00009 #include "route_tree_timing.h"
00010 #include "route_timing.h"
00011 #include "timing_place_lookup.h"
00012 #include "rr_graph.h"
00013 #include "mst.h"
00014 #include "route_export.h"
00015 #include <assert.h>
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define NET_COUNT 1
00037
00038
00039
00040 #define NET_USED 0
00041
00042 #define NET_USED_SOURCE_BLOCK 0
00043 #define NET_USED_SINK_BLOCK 1
00044 #define SOURCE_BLOCK 0
00045 #define SINK_BLOCK 1
00046
00047 #define BLOCK_COUNT 2
00048
00049
00050
00051
00052
00053
00054 #define NUM_TYPES_USED 3
00055
00056 #define DEBUG_TIMING_PLACE_LOOKUP
00057
00058 #define DUMPFILE "lookup_dump.echo"
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 float **delta_io_to_fb;
00069 float **delta_fb_to_fb;
00070 float **delta_fb_to_io;
00071 float **delta_io_to_io;
00072
00073
00074
00075
00076
00077
00078
00079 static float **net_delay;
00080 static float **net_slack;
00081 static float *pin_criticality;
00082 static int *sink_order;
00083 static t_rt_node **rt_node_of_sink;
00084 static t_type_ptr IO_TYPE_BACKUP;
00085 static t_type_ptr EMPTY_TYPE_BACKUP;
00086 static t_type_ptr FILL_TYPE_BACKUP;
00087 static t_type_descriptor dummy_type_descriptors[NUM_TYPES_USED];
00088 static t_type_descriptor *type_descriptors_backup;
00089 static struct s_grid_tile **grid_backup;
00090 static int num_types_backup;
00091
00092 static t_ivec **clb_opins_used_locally;
00093
00094 #ifdef PRINT_ARRAYS
00095 static FILE *lookup_dump;
00096
00097 #endif
00098
00099
00100
00101 static void alloc_net(void);
00102
00103 static void alloc_block(void);
00104
00105 static void load_simplified_device(void);
00106 static void restore_original_device(void);
00107
00108 static void alloc_and_assign_internal_structures(struct s_net **original_net,
00109 struct s_block
00110 **original_block,
00111 int *original_num_nets,
00112 int *original_num_blocks);
00113
00114 static void free_and_reset_internal_structures(struct s_net *original_net,
00115 struct s_block *original_block,
00116 int original_num_nets,
00117 int original_num_blocks);
00118
00119 static void setup_chan_width(struct s_router_opts router_opts,
00120 t_chan_width_dist chan_width_dist);
00121
00122 static void alloc_routing_structs(struct s_router_opts router_opts,
00123 struct s_det_routing_arch det_routing_arch,
00124 t_segment_inf * segment_inf,
00125 t_timing_inf timing_inf,
00126 t_subblock_data subblock_data);
00127
00128 static void free_routing_structs(struct s_router_opts router_opts,
00129 struct s_det_routing_arch det_routing_arch,
00130 t_segment_inf * segment_inf,
00131 t_timing_inf timing_inf);
00132
00133 static void assign_locations(t_type_ptr source_type,
00134 int source_x_loc,
00135 int source_y_loc,
00136 int source_z_loc,
00137 t_type_ptr sink_type,
00138 int sink_x_loc,
00139 int sink_y_loc,
00140 int sink_z_loc);
00141
00142 static float assign_blocks_and_route_net(t_type_ptr source_type,
00143 int source_x_loc,
00144 int source_y_loc,
00145 t_type_ptr sink_type,
00146 int sink_x_loc,
00147 int sink_y_loc,
00148 struct s_router_opts router_opts,
00149 struct s_det_routing_arch
00150 det_routing_arch,
00151 t_segment_inf * segment_inf,
00152 t_timing_inf timing_inf);
00153
00154 static void alloc_delta_arrays(void);
00155
00156 static void free_delta_arrays(void);
00157
00158 static void generic_compute_matrix(float ***matrix_ptr,
00159 t_type_ptr source_type,
00160 t_type_ptr sink_type,
00161 int source_x,
00162 int source_y,
00163 int start_x,
00164 int end_x,
00165 int start_y,
00166 int end_y,
00167 struct s_router_opts router_opts,
00168 struct s_det_routing_arch det_routing_arch,
00169 t_segment_inf * segment_inf,
00170 t_timing_inf timing_inf);
00171
00172 static void compute_delta_fb_to_fb(struct s_router_opts router_opts,
00173 struct s_det_routing_arch det_routing_arch,
00174 t_segment_inf * segment_inf,
00175 t_timing_inf timing_inf,
00176 int longest_length);
00177
00178 static void compute_delta_io_to_fb(struct s_router_opts router_opts,
00179 struct s_det_routing_arch det_routing_arch,
00180 t_segment_inf * segment_inf,
00181 t_timing_inf timing_inf);
00182
00183 static void compute_delta_fb_to_io(struct s_router_opts router_opts,
00184 struct s_det_routing_arch det_routing_arch,
00185 t_segment_inf * segment_inf,
00186 t_timing_inf timing_inf);
00187
00188 static void compute_delta_io_to_io(struct s_router_opts router_opts,
00189 struct s_det_routing_arch det_routing_arch,
00190 t_segment_inf * segment_inf,
00191 t_timing_inf timing_inf);
00192
00193 static void compute_delta_arrays(struct s_router_opts router_opts,
00194 struct s_det_routing_arch det_routing_arch,
00195 t_segment_inf * segment_inf,
00196 t_timing_inf timing_inf,
00197 int longest_length);
00198
00199 static int get_first_pin(enum e_pin_type pintype,
00200 t_type_ptr type);
00201
00202 static int get_longest_segment_length(struct s_det_routing_arch
00203 det_routing_arch,
00204 t_segment_inf * segment_inf);
00205 static void reset_placement(void);
00206
00207 #ifdef PRINT_ARRAYS
00208 static void print_array(float **array_to_print,
00209 int x1,
00210 int x2,
00211 int y1,
00212 int y2);
00213 #endif
00214
00215 static int
00216 get_first_pin(enum e_pin_type pintype,
00217 t_type_ptr type)
00218 {
00219
00220
00221
00222
00223 int i, currpin;
00224
00225 currpin = 0;
00226 for(i = 0; i < type->num_class; i++)
00227 {
00228 if(type->class_inf[i].type == pintype
00229 && !type->is_global_pin[currpin])
00230 return (type->class_inf[i].pinlist[0]);
00231 else
00232 currpin += type->class_inf[i].num_pins;
00233 }
00234 assert(0);
00235 exit(0);
00236 }
00237
00238
00239 static int
00240 get_longest_segment_length(struct s_det_routing_arch det_routing_arch,
00241 t_segment_inf * segment_inf)
00242 {
00243
00244 int i, length;
00245
00246 length = 0;
00247 for(i = 0; i < det_routing_arch.num_segment; i++)
00248 {
00249 if(segment_inf[i].length > length)
00250 length = segment_inf[i].length;
00251 }
00252 return (length);
00253 }
00254
00255
00256 static void
00257 alloc_net(void)
00258 {
00259
00260 int i, len;
00261
00262 net = (struct s_net *)my_malloc(num_nets * sizeof(struct s_net));
00263 for(i = 0; i < NET_COUNT; i++)
00264 {
00265
00266 len = strlen("TEMP_NET");
00267 net[i].name = (char *)my_malloc((len + 1) * sizeof(char));
00268 net[i].is_global = FALSE;
00269 strcpy(net[NET_USED].name, "TEMP_NET");
00270
00271 net[i].num_sinks = (BLOCK_COUNT - 1);
00272 net[i].node_block = (int *)my_malloc(BLOCK_COUNT * sizeof(int));
00273 net[i].node_block[NET_USED_SOURCE_BLOCK] = NET_USED_SOURCE_BLOCK;
00274 net[i].node_block[NET_USED_SINK_BLOCK] = NET_USED_SINK_BLOCK;
00275
00276 net[i].node_block_pin =
00277 (int *)my_malloc(BLOCK_COUNT * sizeof(int));
00278
00279
00280 }
00281 }
00282
00283
00284 static void
00285 alloc_block(void)
00286 {
00287
00288
00289
00290
00291
00292 int ix_b, ix_p, len, i;
00293 int max_pins;
00294
00295 max_pins = 0;
00296 for(i = 0; i < NUM_TYPES_USED; i++)
00297 {
00298 max_pins = max(max_pins, type_descriptors[i].num_pins);
00299 }
00300
00301 block = (struct s_block *)my_malloc(num_blocks * sizeof(struct s_block));
00302
00303 for(ix_b = 0; ix_b < BLOCK_COUNT; ix_b++)
00304 {
00305 len = strlen("TEMP_BLOCK");
00306 block[ix_b].name = (char *)my_malloc((len + 1) * sizeof(char));
00307 strcpy(block[ix_b].name, "TEMP_BLOCK");
00308
00309 block[ix_b].nets = (int *)my_malloc(max_pins * sizeof(int));
00310 block[ix_b].nets[0] = 0;
00311 for(ix_p = 1; ix_p < max_pins; ix_p++)
00312 block[ix_b].nets[ix_p] = OPEN;
00313 }
00314 }
00315
00316
00317 static void
00318 load_simplified_device(void)
00319 {
00320 int i, j;
00321
00322
00323 EMPTY_TYPE_BACKUP = EMPTY_TYPE;
00324 IO_TYPE_BACKUP = IO_TYPE;
00325 FILL_TYPE_BACKUP = FILL_TYPE;
00326 type_descriptors_backup = type_descriptors;
00327 num_types_backup = num_types;
00328 num_types = NUM_TYPES_USED;
00329
00330
00331 dummy_type_descriptors[0] = *EMPTY_TYPE;
00332 dummy_type_descriptors[0].index = 0;
00333 dummy_type_descriptors[1] = *IO_TYPE;
00334 dummy_type_descriptors[1].index = 1;
00335 dummy_type_descriptors[2] = *FILL_TYPE;
00336 dummy_type_descriptors[2].index = 2;
00337 type_descriptors = dummy_type_descriptors;
00338 EMPTY_TYPE = &dummy_type_descriptors[0];
00339 IO_TYPE = &dummy_type_descriptors[1];
00340 FILL_TYPE = &dummy_type_descriptors[2];
00341
00342
00343 grid_backup = grid;
00344 grid =
00345 (struct s_grid_tile **)alloc_matrix(0, nx + 1, 0, ny + 1,
00346 sizeof(struct s_grid_tile));
00347 for(i = 0; i < nx + 2; i++)
00348 {
00349 for(j = 0; j < ny + 2; j++)
00350 {
00351 if((i == 0 && j == 0) ||
00352 (i == nx + 1 && j == 0) ||
00353 (i == 0 && j == ny + 1) || (i == nx + 1
00354 && j == ny + 1))
00355 {
00356 grid[i][j].type = EMPTY_TYPE;
00357 }
00358 else if(i == 0 || i == nx + 1 || j == 0 || j == ny + 1)
00359 {
00360 grid[i][j].type = IO_TYPE;
00361 }
00362 else
00363 {
00364 grid[i][j].type = FILL_TYPE;
00365 }
00366 grid[i][j].blocks =
00367 my_malloc(grid[i][j].type->capacity * sizeof(int));
00368 grid[i][j].offset = 0;
00369 }
00370 }
00371 }
00372 static void
00373 restore_original_device(void)
00374 {
00375 int i, j;
00376
00377
00378 IO_TYPE = IO_TYPE_BACKUP;
00379 EMPTY_TYPE = EMPTY_TYPE_BACKUP;
00380 FILL_TYPE = FILL_TYPE_BACKUP;
00381 type_descriptors = type_descriptors_backup;
00382 num_types = num_types_backup;
00383
00384
00385 for(i = 0; i < nx + 2; i++)
00386 {
00387 for(j = 0; j < ny + 2; j++)
00388 {
00389 free(grid[i][j].blocks);
00390 }
00391 }
00392 free_matrix(grid, 0, nx + 1, 0, sizeof(struct s_grid_tile));
00393 grid = grid_backup;
00394 }
00395
00396
00397 static void
00398 reset_placement(void)
00399 {
00400 int i, j, k;
00401
00402 for(i = 0; i <= nx + 1; i++)
00403 {
00404 for(j = 0; j <= ny + 1; j++)
00405 {
00406 grid[i][j].usage = 0;
00407 for(k = 0; k < grid[i][j].type->capacity; k++)
00408 {
00409 grid[i][j].blocks[k] = EMPTY;
00410 }
00411 }
00412 }
00413 }
00414
00415
00416 static void
00417 alloc_and_assign_internal_structures(struct s_net **original_net,
00418 struct s_block **original_block,
00419 int *original_num_nets,
00420 int *original_num_blocks)
00421 {
00422
00423
00424 *original_net = net;
00425 *original_num_nets = num_nets;
00426 num_nets = NET_COUNT;
00427 alloc_net();
00428
00429 *original_block = block;
00430 *original_num_blocks = num_blocks;
00431 num_blocks = BLOCK_COUNT;
00432 alloc_block();
00433
00434
00435
00436 net_delay =
00437 (float **)alloc_matrix(0, NET_COUNT - 1, 1, BLOCK_COUNT - 1,
00438 sizeof(float));
00439 net_slack =
00440 (float **)alloc_matrix(0, NET_COUNT - 1, 1, BLOCK_COUNT - 1,
00441 sizeof(float));
00442
00443 reset_placement();
00444 }
00445
00446
00447 static void
00448 free_and_reset_internal_structures(struct s_net *original_net,
00449 struct s_block *original_block,
00450 int original_num_nets,
00451 int original_num_blocks)
00452 {
00453
00454
00455
00456 int i;
00457
00458
00459
00460 for(i = 0; i < NET_COUNT; i++)
00461 {
00462 free(net[i].name);
00463 free(net[i].node_block);
00464 free(net[i].node_block_pin);
00465 }
00466 free(net);
00467 net = original_net;
00468
00469 for(i = 0; i < BLOCK_COUNT; i++)
00470 {
00471 free(block[i].name);
00472 free(block[i].nets);
00473 }
00474 free(block);
00475 block = original_block;
00476
00477 num_nets = original_num_nets;
00478 num_blocks = original_num_blocks;
00479
00480 free_matrix(net_delay, 0, NET_COUNT - 1, 1, sizeof(float));
00481 free_matrix(net_slack, 0, NET_COUNT - 1, 1, sizeof(float));
00482
00483 }
00484
00485
00486 static void
00487 setup_chan_width(struct s_router_opts router_opts,
00488 t_chan_width_dist chan_width_dist)
00489 {
00490
00491
00492
00493 int width_fac, i, max_pins_per_fb;
00494
00495 max_pins_per_fb = 0;
00496 for(i = 0; i < num_types; i++)
00497 {
00498 max_pins_per_fb =
00499 max(max_pins_per_fb, type_descriptors[i].num_pins);
00500 }
00501
00502 if(router_opts.fixed_channel_width == NO_FIXED_CHANNEL_WIDTH)
00503 width_fac = 4 * max_pins_per_fb;
00504
00505
00506 else
00507 width_fac = router_opts.fixed_channel_width;
00508
00509 init_chan(width_fac, chan_width_dist);
00510 }
00511
00512
00513 static void
00514 alloc_routing_structs(struct s_router_opts router_opts,
00515 struct s_det_routing_arch det_routing_arch,
00516 t_segment_inf * segment_inf,
00517 t_timing_inf timing_inf,
00518 t_subblock_data subblock_data)
00519 {
00520
00521 int bb_factor;
00522 int warnings;
00523 t_graph_type graph_type;
00524
00525
00526
00527
00528
00529
00530 assign_locations(FILL_TYPE, 1, 1, 0, FILL_TYPE, nx, ny, 0);
00531
00532 clb_opins_used_locally = alloc_route_structs(subblock_data);
00533
00534 free_rr_graph();
00535
00536 if(router_opts.route_type == GLOBAL) {
00537 graph_type = GRAPH_GLOBAL;
00538 } else {
00539 graph_type = (det_routing_arch.directionality ==
00540 BI_DIRECTIONAL ? GRAPH_BIDIR : GRAPH_UNIDIR);
00541 }
00542
00543 build_rr_graph(graph_type, num_types, dummy_type_descriptors, nx,
00544 ny, grid, chan_width_x[0], NULL,
00545 det_routing_arch.switch_block_type,
00546 det_routing_arch.Fs, det_routing_arch.num_segment, det_routing_arch.num_switch,
00547 segment_inf, det_routing_arch.global_route_switch,
00548 det_routing_arch.delayless_switch, timing_inf,
00549 det_routing_arch.wire_to_ipin_switch,
00550 router_opts.base_cost_type, &warnings);
00551
00552 alloc_and_load_rr_node_route_structs();
00553
00554 alloc_timing_driven_route_structs(&pin_criticality, &sink_order,
00555 &rt_node_of_sink);
00556
00557
00558 bb_factor = nx + ny;
00559 init_route_structs(bb_factor);
00560 }
00561
00562
00563 static void
00564 free_routing_structs(struct s_router_opts router_opts,
00565 struct s_det_routing_arch det_routing_arch,
00566 t_segment_inf * segment_inf,
00567 t_timing_inf timing_inf)
00568 {
00569 free_rr_graph();
00570
00571 free_rr_node_route_structs();
00572 free_route_structs(clb_opins_used_locally);
00573 free_trace_structs();
00574
00575 free_timing_driven_route_structs(pin_criticality, sink_order,
00576 rt_node_of_sink);
00577 }
00578
00579
00580 static void
00581 assign_locations(t_type_ptr source_type,
00582 int source_x_loc,
00583 int source_y_loc,
00584 int source_z_loc,
00585 t_type_ptr sink_type,
00586 int sink_x_loc,
00587 int sink_y_loc,
00588 int sink_z_loc)
00589 {
00590
00591 block[SOURCE_BLOCK].type = source_type;
00592 block[SOURCE_BLOCK].x = source_x_loc;
00593 block[SOURCE_BLOCK].y = source_y_loc;
00594 block[SOURCE_BLOCK].z = source_z_loc;
00595
00596 block[SINK_BLOCK].type = sink_type;
00597 block[SINK_BLOCK].x = sink_x_loc;
00598 block[SINK_BLOCK].y = sink_y_loc;
00599 block[SINK_BLOCK].z = sink_z_loc;
00600
00601 grid[source_x_loc][source_y_loc].blocks[source_z_loc] = SOURCE_BLOCK;
00602 grid[sink_x_loc][sink_y_loc].blocks[sink_z_loc] = SINK_BLOCK;
00603
00604 net[NET_USED].node_block_pin[NET_USED_SOURCE_BLOCK] =
00605 get_first_pin(DRIVER, block[SOURCE_BLOCK].type);
00606 net[NET_USED].node_block_pin[NET_USED_SINK_BLOCK] =
00607 get_first_pin(RECEIVER, block[SINK_BLOCK].type);
00608
00609 grid[source_x_loc][source_y_loc].usage += 1;
00610 grid[sink_x_loc][sink_y_loc].usage += 1;
00611
00612 }
00613
00614
00615 static float
00616 assign_blocks_and_route_net(t_type_ptr source_type,
00617 int source_x_loc,
00618 int source_y_loc,
00619 t_type_ptr sink_type,
00620 int sink_x_loc,
00621 int sink_y_loc,
00622 struct s_router_opts router_opts,
00623 struct s_det_routing_arch det_routing_arch,
00624 t_segment_inf * segment_inf,
00625 t_timing_inf timing_inf)
00626 {
00627
00628
00629 boolean is_routeable;
00630 int ipin;
00631 float pres_fac, T_crit;
00632 float net_delay_value;
00633
00634 int source_z_loc, sink_z_loc;
00635
00636
00637 source_z_loc = 0;
00638 sink_z_loc = 0;
00639
00640 net_delay_value = IMPOSSIBLE;
00641
00642 assign_locations(source_type, source_x_loc, source_y_loc, source_z_loc,
00643 sink_type, sink_x_loc, sink_y_loc, sink_z_loc);
00644
00645 load_net_rr_terminals(rr_node_indices);
00646
00647 T_crit = 1;
00648 pres_fac = 0;
00649
00650 for(ipin = 1; ipin <= net[NET_USED].num_sinks; ipin++)
00651 net_slack[NET_USED][ipin] = 0;
00652
00653 is_routeable = timing_driven_route_net(NET_USED, pres_fac,
00654 router_opts.max_criticality,
00655 router_opts.criticality_exp,
00656 router_opts.astar_fac,
00657 router_opts.bend_cost,
00658 net_slack[NET_USED],
00659 pin_criticality, sink_order,
00660 rt_node_of_sink, T_crit,
00661 net_delay[NET_USED]);
00662
00663 net_delay_value = net_delay[NET_USED][NET_USED_SINK_BLOCK];
00664
00665 grid[source_x_loc][source_y_loc].usage = 0;
00666 grid[source_x_loc][source_y_loc].blocks[source_z_loc] = EMPTY;
00667 grid[sink_x_loc][sink_y_loc].usage = 0;
00668 grid[sink_x_loc][sink_y_loc].blocks[sink_z_loc] = EMPTY;
00669
00670 return (net_delay_value);
00671 }
00672
00673
00674 static void
00675 alloc_delta_arrays(void)
00676 {
00677 int id_x, id_y;
00678
00679 delta_fb_to_fb =
00680 (float **)alloc_matrix(0, nx - 1, 0, ny - 1, sizeof(float));
00681 delta_io_to_fb = (float **)alloc_matrix(0, nx, 0, ny, sizeof(float));
00682 delta_fb_to_io = (float **)alloc_matrix(0, nx, 0, ny, sizeof(float));
00683 delta_io_to_io =
00684 (float **)alloc_matrix(0, nx + 1, 0, ny + 1, sizeof(float));
00685
00686
00687
00688
00689 for(id_x = 0; id_x <= nx; id_x++)
00690 {
00691 for(id_y = 0; id_y <= ny; id_y++)
00692 {
00693 delta_io_to_fb[id_x][id_y] = IMPOSSIBLE;
00694 }
00695 }
00696 for(id_x = 0; id_x <= nx - 1; id_x++)
00697 {
00698 for(id_y = 0; id_y <= ny - 1; id_y++)
00699 {
00700 delta_fb_to_fb[id_x][id_y] = IMPOSSIBLE;
00701 }
00702 }
00703 for(id_x = 0; id_x <= nx; id_x++)
00704 {
00705 for(id_y = 0; id_y <= ny; id_y++)
00706 {
00707 delta_fb_to_io[id_x][id_y] = IMPOSSIBLE;
00708 }
00709 }
00710 for(id_x = 0; id_x <= nx + 1; id_x++)
00711 {
00712 for(id_y = 0; id_y <= ny + 1; id_y++)
00713 {
00714 delta_io_to_io[id_x][id_y] = IMPOSSIBLE;
00715 }
00716 }
00717 }
00718
00719
00720 static void
00721 free_delta_arrays(void)
00722 {
00723
00724 free_matrix(delta_io_to_fb, 0, nx, 0, sizeof(float));
00725 free_matrix(delta_fb_to_fb, 0, nx - 1, 0, sizeof(float));
00726 free_matrix(delta_fb_to_io, 0, nx, 0, sizeof(float));
00727 free_matrix(delta_io_to_io, 0, nx + 1, 0, sizeof(float));
00728
00729 }
00730
00731
00732 static void
00733 generic_compute_matrix(float ***matrix_ptr,
00734 t_type_ptr source_type,
00735 t_type_ptr sink_type,
00736 int source_x,
00737 int source_y,
00738 int start_x,
00739 int end_x,
00740 int start_y,
00741 int end_y,
00742 struct s_router_opts router_opts,
00743 struct s_det_routing_arch det_routing_arch,
00744 t_segment_inf * segment_inf,
00745 t_timing_inf timing_inf)
00746 {
00747
00748 int delta_x, delta_y;
00749 int sink_x, sink_y;
00750
00751 for(sink_x = start_x; sink_x <= end_x; sink_x++)
00752 {
00753 for(sink_y = start_y; sink_y <= end_y; sink_y++)
00754 {
00755 delta_x = abs(sink_x - source_x);
00756 delta_y = abs(sink_y - source_y);
00757
00758 if(delta_x == 0 && delta_y == 0)
00759 continue;
00760
00761
00762 (*matrix_ptr)[delta_x][delta_y] =
00763 assign_blocks_and_route_net(source_type, source_x,
00764 source_y, sink_type,
00765 sink_x, sink_y,
00766 router_opts,
00767 det_routing_arch,
00768 segment_inf, timing_inf);
00769 }
00770 }
00771 }
00772
00773
00774 static void
00775 compute_delta_fb_to_fb(struct s_router_opts router_opts,
00776 struct s_det_routing_arch det_routing_arch,
00777 t_segment_inf * segment_inf,
00778 t_timing_inf timing_inf,
00779 int longest_length)
00780 {
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 int source_x, source_y, sink_x, sink_y;
00791 int start_x, start_y, end_x, end_y;
00792 int delta_x, delta_y;
00793 t_type_ptr source_type, sink_type;
00794
00795 source_type = FILL_TYPE;
00796 sink_type = FILL_TYPE;
00797
00798 if(longest_length < 0.5 * (nx))
00799 {
00800 start_x = longest_length;
00801 }
00802 else
00803 {
00804 start_x = (int)(0.5 * nx);
00805 }
00806 end_x = nx;
00807 source_x = start_x;
00808
00809 if(longest_length < 0.5 * (ny))
00810 {
00811 start_y = longest_length;
00812 }
00813 else
00814 {
00815 start_y = (int)(0.5 * ny);
00816 }
00817 end_y = ny;
00818 source_y = start_y;
00819
00820
00821
00822 for(sink_x = start_x; sink_x <= end_x - 1; sink_x++)
00823 {
00824 for(sink_y = start_y; sink_y <= end_y - 1; sink_y++)
00825 {
00826 delta_x = abs(sink_x - source_x);
00827 delta_y = abs(sink_y - source_y);
00828
00829 if(delta_x == 0 && delta_y == 0)
00830 {
00831 delta_fb_to_fb[delta_x][delta_y] = 0.0;
00832 continue;
00833 }
00834 delta_fb_to_fb[delta_x][delta_y] =
00835 assign_blocks_and_route_net(source_type, source_x,
00836 source_y, sink_type,
00837 sink_x, sink_y,
00838 router_opts,
00839 det_routing_arch,
00840 segment_inf, timing_inf);
00841 }
00842
00843 }
00844
00845
00846 sink_x = end_x - 1;
00847 sink_y = end_y - 1;
00848
00849 for(source_x = start_x - 1; source_x >= 1; source_x--)
00850 {
00851 for(source_y = start_y; source_y <= end_y - 1; source_y++)
00852 {
00853 delta_x = abs(sink_x - source_x);
00854 delta_y = abs(sink_y - source_y);
00855
00856 delta_fb_to_fb[delta_x][delta_y] =
00857 assign_blocks_and_route_net(source_type, source_x,
00858 source_y, sink_type,
00859 sink_x, sink_y,
00860 router_opts,
00861 det_routing_arch,
00862 segment_inf, timing_inf);
00863 }
00864 }
00865
00866 for(source_x = 1; source_x <= end_x - 1; source_x++)
00867 {
00868 for(source_y = 1; source_y < start_y; source_y++)
00869 {
00870 delta_x = abs(sink_x - source_x);
00871 delta_y = abs(sink_y - source_y);
00872
00873 delta_fb_to_fb[delta_x][delta_y] =
00874 assign_blocks_and_route_net(source_type, source_x,
00875 source_y, sink_type,
00876 sink_x, sink_y,
00877 router_opts,
00878 det_routing_arch,
00879 segment_inf, timing_inf);
00880 }
00881 }
00882
00883
00884
00885 sink_x = end_x;
00886 sink_y = end_y;
00887 source_x = 1;
00888 for(source_y = 1; source_y <= end_y; source_y++)
00889 {
00890 delta_x = abs(sink_x - source_x);
00891 delta_y = abs(sink_y - source_y);
00892
00893 delta_fb_to_fb[delta_x][delta_y] =
00894 assign_blocks_and_route_net(source_type, source_x, source_y,
00895 sink_type, sink_x, sink_y,
00896 router_opts, det_routing_arch,
00897 segment_inf, timing_inf);
00898
00899 }
00900
00901 sink_x = end_x;
00902 sink_y = end_y;
00903 source_y = 1;
00904 for(source_x = 1; source_x <= end_x; source_x++)
00905 {
00906 delta_x = abs(sink_x - source_x);
00907 delta_y = abs(sink_y - source_y);
00908
00909 delta_fb_to_fb[delta_x][delta_y] =
00910 assign_blocks_and_route_net(source_type, source_x, source_y,
00911 sink_type, sink_x, sink_y,
00912 router_opts, det_routing_arch,
00913 segment_inf, timing_inf);
00914 }
00915 }
00916
00917
00918 static void
00919 compute_delta_io_to_fb(struct s_router_opts router_opts,
00920 struct s_det_routing_arch det_routing_arch,
00921 t_segment_inf * segment_inf,
00922 t_timing_inf timing_inf)
00923 {
00924 int source_x, source_y;
00925 int start_x, start_y, end_x, end_y;
00926 t_type_ptr source_type, sink_type;
00927
00928 source_type = IO_TYPE;
00929 sink_type = FILL_TYPE;
00930
00931 delta_io_to_fb[0][0] = IMPOSSIBLE;
00932 delta_io_to_fb[nx][ny] = IMPOSSIBLE;
00933
00934 source_x = 0;
00935 source_y = 1;
00936
00937 start_x = 1;
00938 end_x = nx;
00939 start_y = 1;
00940 end_y = ny;
00941 generic_compute_matrix(&delta_io_to_fb, source_type, sink_type,
00942 source_x, source_y, start_x, end_x, start_y,
00943 end_y, router_opts, det_routing_arch,
00944 segment_inf, timing_inf);
00945
00946 source_x = 1;
00947 source_y = 0;
00948
00949 start_x = 1;
00950 end_x = 1;
00951 start_y = 1;
00952 end_y = ny;
00953 generic_compute_matrix(&delta_io_to_fb, source_type, sink_type,
00954 source_x, source_y, start_x, end_x, start_y,
00955 end_y, router_opts, det_routing_arch,
00956 segment_inf, timing_inf);
00957
00958 start_x = 1;
00959 end_x = nx;
00960 start_y = ny;
00961 end_y = ny;
00962 generic_compute_matrix(&delta_io_to_fb, source_type, sink_type,
00963 source_x, source_y, start_x, end_x, start_y,
00964 end_y, router_opts, det_routing_arch,
00965 segment_inf, timing_inf);
00966 }
00967
00968
00969 static void
00970 compute_delta_fb_to_io(struct s_router_opts router_opts,
00971 struct s_det_routing_arch det_routing_arch,
00972 t_segment_inf * segment_inf,
00973 t_timing_inf timing_inf)
00974 {
00975 int source_x, source_y, sink_x, sink_y;
00976 int delta_x, delta_y;
00977 t_type_ptr source_type, sink_type;
00978
00979 source_type = FILL_TYPE;
00980 sink_type = IO_TYPE;
00981
00982 delta_fb_to_io[0][0] = IMPOSSIBLE;
00983 delta_fb_to_io[nx][ny] = IMPOSSIBLE;
00984
00985 sink_x = 0;
00986 sink_y = 1;
00987 for(source_x = 1; source_x <= nx; source_x++)
00988 {
00989 for(source_y = 1; source_y <= ny; source_y++)
00990 {
00991 delta_x = abs(source_x - sink_x);
00992 delta_y = abs(source_y - sink_y);
00993
00994 delta_fb_to_io[delta_x][delta_y] =
00995 assign_blocks_and_route_net(source_type, source_x,
00996 source_y, sink_type,
00997 sink_x, sink_y,
00998 router_opts,
00999 det_routing_arch,
01000 segment_inf, timing_inf);
01001 }
01002 }
01003
01004 sink_x = 1;
01005 sink_y = 0;
01006 source_x = 1;
01007 delta_x = abs(source_x - sink_x);
01008 for(source_y = 1; source_y <= ny; source_y++)
01009 {
01010 delta_y = abs(source_y - sink_y);
01011 delta_fb_to_io[delta_x][delta_y] =
01012 assign_blocks_and_route_net(source_type, source_x, source_y,
01013 sink_type, sink_x, sink_y,
01014 router_opts, det_routing_arch,
01015 segment_inf, timing_inf);
01016 }
01017
01018 sink_x = 1;
01019 sink_y = 0;
01020 source_y = ny;
01021 delta_y = abs(source_y - sink_y);
01022 for(source_x = 2; source_x <= nx; source_x++)
01023 {
01024 delta_x = abs(source_x - sink_x);
01025 delta_fb_to_io[delta_x][delta_y] =
01026 assign_blocks_and_route_net(source_type, source_x, source_y,
01027 sink_type, sink_x, sink_y,
01028 router_opts, det_routing_arch,
01029 segment_inf, timing_inf);
01030 }
01031 }
01032
01033
01034 static void
01035 compute_delta_io_to_io(struct s_router_opts router_opts,
01036 struct s_det_routing_arch det_routing_arch,
01037 t_segment_inf * segment_inf,
01038 t_timing_inf timing_inf)
01039 {
01040 int source_x, source_y, sink_x, sink_y;
01041 int delta_x, delta_y;
01042 t_type_ptr source_type, sink_type;
01043
01044 source_type = IO_TYPE;
01045 sink_type = IO_TYPE;
01046
01047 delta_io_to_io[0][0] = 0;
01048 delta_io_to_io[nx + 1][ny + 1] = IMPOSSIBLE;
01049 delta_io_to_io[0][ny] = IMPOSSIBLE;
01050 delta_io_to_io[nx][0] = IMPOSSIBLE;
01051 delta_io_to_io[nx][ny + 1] = IMPOSSIBLE;
01052 delta_io_to_io[nx + 1][ny] = IMPOSSIBLE;
01053
01054
01055 source_x = 0;
01056 source_y = 1;
01057 sink_x = 0;
01058 delta_x = abs(sink_x - source_x);
01059
01060
01061 for(sink_y = 2; sink_y <= ny; sink_y++)
01062 {
01063 delta_y = abs(sink_y - source_y);
01064 delta_io_to_io[delta_x][delta_y] =
01065 assign_blocks_and_route_net(source_type, source_x, source_y,
01066 sink_type, sink_x, sink_y,
01067 router_opts, det_routing_arch,
01068 segment_inf, timing_inf);
01069
01070 }
01071
01072 source_x = 0;
01073 source_y = 1;
01074 sink_x = nx + 1;
01075 delta_x = abs(sink_x - source_x);
01076
01077 for(sink_y = 1; sink_y <= ny; sink_y++)
01078 {
01079 delta_y = abs(sink_y - source_y);
01080 delta_io_to_io[delta_x][delta_y] =
01081 assign_blocks_and_route_net(source_type, source_x, source_y,
01082 sink_type, sink_x, sink_y,
01083 router_opts, det_routing_arch,
01084 segment_inf, timing_inf);
01085
01086 }
01087
01088
01089 source_x = 1;
01090 source_y = 0;
01091 sink_y = 0;
01092 delta_y = abs(sink_y - source_y);
01093
01094 for(sink_x = 2; sink_x <= nx; sink_x++)
01095 {
01096 delta_x = abs(sink_x - source_x);
01097 delta_io_to_io[delta_x][delta_y] =
01098 assign_blocks_and_route_net(source_type, source_x, source_y,
01099 sink_type, sink_x, sink_y,
01100 router_opts, det_routing_arch,
01101 segment_inf, timing_inf);
01102
01103 }
01104
01105 source_x = 1;
01106 source_y = 0;
01107 sink_y = ny + 1;
01108 delta_y = abs(sink_y - source_y);
01109
01110 for(sink_x = 1; sink_x <= nx; sink_x++)
01111 {
01112 delta_x = abs(sink_x - source_x);
01113 delta_io_to_io[delta_x][delta_y] =
01114 assign_blocks_and_route_net(source_type, source_x, source_y,
01115 sink_type, sink_x, sink_y,
01116 router_opts, det_routing_arch,
01117 segment_inf, timing_inf);
01118
01119 }
01120
01121 source_x = 0;
01122 sink_y = ny + 1;
01123 for(source_y = 1; source_y <= ny; source_y++)
01124 {
01125 for(sink_x = 1; sink_x <= nx; sink_x++)
01126 {
01127 delta_y = abs(source_y - sink_y);
01128 delta_x = abs(source_x - sink_x);
01129 delta_io_to_io[delta_x][delta_y] =
01130 assign_blocks_and_route_net(source_type, source_x,
01131 source_y, sink_type,
01132 sink_x, sink_y,
01133 router_opts,
01134 det_routing_arch,
01135 segment_inf, timing_inf);
01136
01137 }
01138 }
01139 }
01140
01141
01142 #ifdef PRINT_ARRAYS
01143 static void
01144 print_array(float **array_to_print,
01145 int x1,
01146 int x2,
01147 int y1,
01148 int y2)
01149 {
01150
01151
01152 int idx_x, idx_y;
01153
01154 fprintf(lookup_dump, "\nPrinting Array \n\n");
01155
01156 for(idx_y = y2; idx_y >= y1; idx_y--)
01157 {
01158 for(idx_x = x1; idx_x <= x2; idx_x++)
01159 {
01160 fprintf(lookup_dump, " %9.2e",
01161 array_to_print[idx_x][idx_y]);
01162 }
01163 fprintf(lookup_dump, "\n");
01164 }
01165 fprintf(lookup_dump, "\n\n");
01166 }
01167 #endif
01168
01169 static void
01170 compute_delta_arrays(struct s_router_opts router_opts,
01171 struct s_det_routing_arch det_routing_arch,
01172 t_segment_inf * segment_inf,
01173 t_timing_inf timing_inf,
01174 int longest_length)
01175 {
01176
01177 printf
01178 ("Computing delta_io_to_io lookup matrix, may take a few seconds, please wait...\n");
01179 compute_delta_io_to_io(router_opts, det_routing_arch, segment_inf,
01180 timing_inf);
01181 printf
01182 ("Computing delta_io_to_fb lookup matrix, may take a few seconds, please wait...\n");
01183 compute_delta_io_to_fb(router_opts, det_routing_arch, segment_inf,
01184 timing_inf);
01185 printf
01186 ("Computing delta_fb_to_io lookup matrix, may take a few seconds, please wait...\n");
01187 compute_delta_fb_to_io(router_opts, det_routing_arch, segment_inf,
01188 timing_inf);
01189 printf
01190 ("Computing delta_fb_to_fb lookup matrix, may take a few seconds, please wait...\n");
01191 compute_delta_fb_to_fb(router_opts, det_routing_arch, segment_inf,
01192 timing_inf, longest_length);
01193
01194 #ifdef PRINT_ARRAYS
01195 lookup_dump = my_fopen(DUMPFILE, "w");
01196 fprintf(lookup_dump, "\n\nprinting delta_fb_to_fb\n");
01197 print_array(delta_fb_to_fb, 0, nx - 1, 0, ny - 1);
01198 fprintf(lookup_dump, "\n\nprinting delta_io_to_fb\n");
01199 print_array(delta_io_to_fb, 0, nx, 0, ny);
01200 fprintf(lookup_dump, "\n\nprinting delta_fb_to_io\n");
01201 print_array(delta_fb_to_io, 0, nx, 0, ny);
01202 fprintf(lookup_dump, "\n\nprinting delta_io_to_io\n");
01203 print_array(delta_io_to_io, 0, nx + 1, 0, ny + 1);
01204 fclose(lookup_dump);
01205 #endif
01206
01207 }
01208
01209
01210
01211
01212 void
01213 compute_delay_lookup_tables(struct s_router_opts router_opts,
01214 struct s_det_routing_arch det_routing_arch,
01215 t_segment_inf * segment_inf,
01216 t_timing_inf timing_inf,
01217 t_chan_width_dist chan_width_dist,
01218 t_subblock_data subblock_data)
01219 {
01220
01221 static struct s_net *original_net;
01222
01223
01224
01225
01226 static struct s_block *original_block;
01227
01228 static int original_num_nets;
01229 static int original_num_blocks;
01230 static int longest_length;
01231
01232 load_simplified_device();
01233
01234 alloc_and_assign_internal_structures(&original_net,
01235 &original_block,
01236 &original_num_nets,
01237 &original_num_blocks);
01238 setup_chan_width(router_opts, chan_width_dist);
01239
01240 alloc_routing_structs(router_opts, det_routing_arch, segment_inf,
01241 timing_inf, subblock_data);
01242
01243 longest_length =
01244 get_longest_segment_length(det_routing_arch, segment_inf);
01245
01246
01247
01248 alloc_delta_arrays();
01249 compute_delta_arrays(router_opts, det_routing_arch, segment_inf,
01250 timing_inf, longest_length);
01251
01252
01253 free_routing_structs(router_opts, det_routing_arch, segment_inf,
01254 timing_inf);
01255
01256 restore_original_device();
01257
01258 free_and_reset_internal_structures(original_net, original_block,
01259 original_num_nets,
01260 original_num_blocks);
01261 }
01262
01263
01264 void
01265 free_place_lookup_structs(void)
01266 {
01267
01268 free_delta_arrays();
01269
01270 }