#include <stdio.h>
#include <math.h>
#include <string.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "route_common.h"
#include "place_and_route.h"
#include "route_tree_timing.h"
#include "route_timing.h"
#include "timing_place_lookup.h"
#include "rr_graph.h"
#include "mst.h"
#include "route_export.h"
#include <assert.h>
Go to the source code of this file.
Defines | |
#define | NET_COUNT 1 |
#define | NET_USED 0 |
#define | NET_USED_SOURCE_BLOCK 0 |
#define | NET_USED_SINK_BLOCK 1 |
#define | SOURCE_BLOCK 0 |
#define | SINK_BLOCK 1 |
#define | BLOCK_COUNT 2 |
#define | NUM_TYPES_USED 3 |
#define | DEBUG_TIMING_PLACE_LOOKUP |
#define | DUMPFILE "lookup_dump.echo" |
Functions | |
static void | alloc_net (void) |
static void | alloc_block (void) |
static void | load_simplified_device (void) |
static void | restore_original_device (void) |
static void | alloc_and_assign_internal_structures (struct s_net **original_net, struct s_block **original_block, int *original_num_nets, int *original_num_blocks) |
static void | free_and_reset_internal_structures (struct s_net *original_net, struct s_block *original_block, int original_num_nets, int original_num_blocks) |
static void | setup_chan_width (struct s_router_opts router_opts, t_chan_width_dist chan_width_dist) |
static void | alloc_routing_structs (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) |
static void | free_routing_structs (struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf) |
static void | assign_locations (t_type_ptr source_type, int source_x_loc, int source_y_loc, int source_z_loc, t_type_ptr sink_type, int sink_x_loc, int sink_y_loc, int sink_z_loc) |
static float | assign_blocks_and_route_net (t_type_ptr source_type, int source_x_loc, int source_y_loc, t_type_ptr sink_type, int sink_x_loc, int sink_y_loc, struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf) |
static void | alloc_delta_arrays (void) |
static void | free_delta_arrays (void) |
static void | generic_compute_matrix (float ***matrix_ptr, t_type_ptr source_type, t_type_ptr sink_type, int source_x, int source_y, int start_x, int end_x, int start_y, int end_y, struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf) |
static void | compute_delta_fb_to_fb (struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf, int longest_length) |
static void | compute_delta_io_to_fb (struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf) |
static void | compute_delta_fb_to_io (struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf) |
static void | compute_delta_io_to_io (struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf) |
static void | compute_delta_arrays (struct s_router_opts router_opts, struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf, t_timing_inf timing_inf, int longest_length) |
static int | get_first_pin (enum e_pin_type pintype, t_type_ptr type) |
static int | get_longest_segment_length (struct s_det_routing_arch det_routing_arch, t_segment_inf *segment_inf) |
static void | reset_placement (void) |
void | compute_delay_lookup_tables (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_chan_width_dist chan_width_dist, t_subblock_data subblock_data) |
void | free_place_lookup_structs (void) |
Variables | |
float ** | delta_io_to_fb |
float ** | delta_fb_to_fb |
float ** | delta_fb_to_io |
float ** | delta_io_to_io |
static float ** | net_delay |
static float ** | net_slack |
static float * | pin_criticality |
static int * | sink_order |
static t_rt_node ** | rt_node_of_sink |
static t_type_ptr | IO_TYPE_BACKUP |
static t_type_ptr | EMPTY_TYPE_BACKUP |
static t_type_ptr | FILL_TYPE_BACKUP |
static t_type_descriptor | dummy_type_descriptors [NUM_TYPES_USED] |
static t_type_descriptor * | type_descriptors_backup |
static struct s_grid_tile ** | grid_backup |
static int | num_types_backup |
static t_ivec ** | clb_opins_used_locally |
#define BLOCK_COUNT 2 |
Definition at line 47 of file timing_place_lookup.c.
#define DEBUG_TIMING_PLACE_LOOKUP |
Definition at line 56 of file timing_place_lookup.c.
#define DUMPFILE "lookup_dump.echo" |
Definition at line 58 of file timing_place_lookup.c.
#define NET_COUNT 1 |
Definition at line 36 of file timing_place_lookup.c.
#define NET_USED 0 |
Definition at line 40 of file timing_place_lookup.c.
#define NET_USED_SINK_BLOCK 1 |
Definition at line 43 of file timing_place_lookup.c.
#define NET_USED_SOURCE_BLOCK 0 |
Definition at line 42 of file timing_place_lookup.c.
#define NUM_TYPES_USED 3 |
Definition at line 54 of file timing_place_lookup.c.
#define SINK_BLOCK 1 |
Definition at line 45 of file timing_place_lookup.c.
#define SOURCE_BLOCK 0 |
Definition at line 44 of file timing_place_lookup.c.
static void alloc_and_assign_internal_structures | ( | struct s_net ** | original_net, | |
struct s_block ** | original_block, | |||
int * | original_num_nets, | |||
int * | original_num_blocks | |||
) | [static] |
Definition at line 417 of file timing_place_lookup.c.
00421 { 00422 /*allocate new data structures to hold net, and block info */ 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 /* [0..num_nets-1][1..num_pins-1] */ 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 }
static void alloc_block | ( | void | ) | [static] |
Definition at line 285 of file timing_place_lookup.c.
00286 { 00287 00288 /*allocates block structure, and assigns values to known parameters */ 00289 /*type and x,y fields are left undefined at this stage since they */ 00290 /*are not known until we start moving blocks through the clb array */ 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 }
static void alloc_delta_arrays | ( | void | ) | [static] |
Definition at line 675 of file timing_place_lookup.c.
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 /*initialize all of the array locations to -1 */ 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 }
static void alloc_net | ( | void | ) | [static] |
Definition at line 257 of file timing_place_lookup.c.
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 /* FIXME: We *really* shouldn't be allocating write-once copies */ 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; /*driving block */ 00274 net[i].node_block[NET_USED_SINK_BLOCK] = NET_USED_SINK_BLOCK; /*target block */ 00275 00276 net[i].node_block_pin = 00277 (int *)my_malloc(BLOCK_COUNT * sizeof(int)); 00278 /*the values for this are allocated in assign_blocks_and_route_net */ 00279 00280 } 00281 }
static void alloc_routing_structs | ( | 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 | |||
) | [static] |
Definition at line 514 of file timing_place_lookup.c.
00519 { 00520 00521 int bb_factor; 00522 int warnings; 00523 t_graph_type graph_type; 00524 00525 /*calls routines that set up routing resource graph and associated structures */ 00526 00527 00528 /*must set up dummy blocks for the first pass through to setup locally used opins */ 00529 /* Only one block per tile */ 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; /*set it to a huge value */ 00559 init_route_structs(bb_factor); 00560 }
static float assign_blocks_and_route_net | ( | t_type_ptr | source_type, | |
int | source_x_loc, | |||
int | source_y_loc, | |||
t_type_ptr | sink_type, | |||
int | sink_x_loc, | |||
int | sink_y_loc, | |||
struct s_router_opts | router_opts, | |||
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf | |||
) | [static] |
Definition at line 616 of file timing_place_lookup.c.
00626 { 00627 /*places blocks at the specified locations, and routes a net between them */ 00628 /*returns the delay of this net */ 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 /* Only one block per tile */ 00637 source_z_loc = 0; 00638 sink_z_loc = 0; 00639 00640 net_delay_value = IMPOSSIBLE; /*set to known value for debug purposes */ 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; /* ignore congestion */ 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 }
static void assign_locations | ( | t_type_ptr | source_type, | |
int | source_x_loc, | |||
int | source_y_loc, | |||
int | source_z_loc, | |||
t_type_ptr | sink_type, | |||
int | sink_x_loc, | |||
int | sink_y_loc, | |||
int | sink_z_loc | |||
) | [static] |
Definition at line 581 of file timing_place_lookup.c.
00589 { 00590 /*all routing occurs between block 0 (source) and block 1 (sink) */ 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 }
void compute_delay_lookup_tables | ( | 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_chan_width_dist | chan_width_dist, | |||
t_subblock_data | subblock_data | |||
) |
Definition at line 1213 of file timing_place_lookup.c.
01219 { 01220 01221 static struct s_net *original_net; /*this will be used as a pointer to remember what */ 01222 01223 /*the "real" nets in the circuit are. This is */ 01224 /*required because we are using the net structure */ 01225 /*in these routines to find delays between blocks */ 01226 static struct s_block *original_block; /*same def as original_nets, but for 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 /*now setup and compute the actual arrays */ 01248 alloc_delta_arrays(); 01249 compute_delta_arrays(router_opts, det_routing_arch, segment_inf, 01250 timing_inf, longest_length); 01251 01252 /*free all data structures that are no longer needed */ 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 }
static void compute_delta_arrays | ( | struct s_router_opts | router_opts, | |
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf, | |||
int | longest_length | |||
) | [static] |
Definition at line 1170 of file timing_place_lookup.c.
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 }
static void compute_delta_fb_to_fb | ( | struct s_router_opts | router_opts, | |
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf, | |||
int | longest_length | |||
) | [static] |
Definition at line 775 of file timing_place_lookup.c.
00780 { 00781 00782 /*this routine must compute delay values in a slightly different way than the */ 00783 /*other compute routines. We cannot use a location close to the edge as the */ 00784 /*source location for the majority of the delay computations because this */ 00785 /*would give gradually increasing delay values. To avoid this from happening */ 00786 /*a clb that is at least longest_length away from an edge should be chosen */ 00787 /*as a source , if longest_length is more than 0.5 of the total size then */ 00788 /*choose a FB at the center as the source FB */ 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 /*don't put the sink all the way to the corner, until it is necessary */ 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 /*now move sink into the top right corner */ 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 }
static void compute_delta_fb_to_io | ( | struct s_router_opts | router_opts, | |
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf | |||
) | [static] |
Definition at line 970 of file timing_place_lookup.c.
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 }
static void compute_delta_io_to_fb | ( | struct s_router_opts | router_opts, | |
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf | |||
) | [static] |
Definition at line 919 of file timing_place_lookup.c.
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 }
static void compute_delta_io_to_io | ( | struct s_router_opts | router_opts, | |
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf | |||
) | [static] |
Definition at line 1035 of file timing_place_lookup.c.
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; /*delay to itself is 0 (this can happen) */ 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 }
static void free_and_reset_internal_structures | ( | struct s_net * | original_net, | |
struct s_block * | original_block, | |||
int | original_num_nets, | |||
int | original_num_blocks | |||
) | [static] |
Definition at line 448 of file timing_place_lookup.c.
00452 { 00453 /*reset gloabal data structures to the state that they were in before these */ 00454 /*lookup computation routines were called */ 00455 00456 int i; 00457 00458 00459 /*there should be only one net to free, but this is safer */ 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 }
static void free_delta_arrays | ( | void | ) | [static] |
Definition at line 721 of file timing_place_lookup.c.
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 }
void free_place_lookup_structs | ( | void | ) |
Definition at line 1265 of file timing_place_lookup.c.
01266 { 01267 01268 free_delta_arrays(); 01269 01270 }
static void free_routing_structs | ( | struct s_router_opts | router_opts, | |
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf | |||
) | [static] |
Definition at line 564 of file timing_place_lookup.c.
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 }
static void generic_compute_matrix | ( | float *** | matrix_ptr, | |
t_type_ptr | source_type, | |||
t_type_ptr | sink_type, | |||
int | source_x, | |||
int | source_y, | |||
int | start_x, | |||
int | end_x, | |||
int | start_y, | |||
int | end_y, | |||
struct s_router_opts | router_opts, | |||
struct s_det_routing_arch | det_routing_arch, | |||
t_segment_inf * | segment_inf, | |||
t_timing_inf | timing_inf | |||
) | [static] |
Definition at line 733 of file timing_place_lookup.c.
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; /*do not compute distance from a block to itself */ 00760 /*if a value is desired, pre-assign it somewhere else */ 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 }
static int get_first_pin | ( | enum e_pin_type | pintype, | |
t_type_ptr | type | |||
) | [static] |
Definition at line 216 of file timing_place_lookup.c.
00218 { 00219 00220 /*this code assumes logical equivilance between all driving pins */ 00221 /*global pins are not hooked up to the temporary net */ 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); /*should never hit this line */ 00236 }
static int get_longest_segment_length | ( | struct s_det_routing_arch | det_routing_arch, | |
t_segment_inf * | segment_inf | |||
) | [static] |
Definition at line 240 of file timing_place_lookup.c.
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 }
static void load_simplified_device | ( | void | ) | [static] |
Definition at line 318 of file timing_place_lookup.c.
00319 { 00320 int i, j; 00321 00322 /* Backup original globals */ 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 /* Fill in homogeneous core type info */ 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 /* Fill in homogeneous core grid info */ 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 }
static void reset_placement | ( | void | ) | [static] |
Definition at line 398 of file timing_place_lookup.c.
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 }
static void restore_original_device | ( | void | ) | [static] |
Definition at line 373 of file timing_place_lookup.c.
00374 { 00375 int i, j; 00376 00377 /* restore previous globals */ 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 /* free allocatd data */ 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 }
static void setup_chan_width | ( | struct s_router_opts | router_opts, | |
t_chan_width_dist | chan_width_dist | |||
) | [static] |
Definition at line 487 of file timing_place_lookup.c.
00489 { 00490 /*we give plenty of tracks, this increases routability for the */ 00491 /*lookup table generation */ 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; /*this is 2x the value that binary search starts */ 00504 /*this should be enough to allow most pins to */ 00505 /*connect to tracks in the architecture */ 00506 else 00507 width_fac = router_opts.fixed_channel_width; 00508 00509 init_chan(width_fac, chan_width_dist); 00510 }
t_ivec** clb_opins_used_locally [static] |
Definition at line 92 of file timing_place_lookup.c.
float** delta_fb_to_fb |
Definition at line 69 of file timing_place_lookup.c.
float** delta_fb_to_io |
Definition at line 70 of file timing_place_lookup.c.
float** delta_io_to_fb |
Definition at line 68 of file timing_place_lookup.c.
float** delta_io_to_io |
Definition at line 71 of file timing_place_lookup.c.
t_type_descriptor dummy_type_descriptors[NUM_TYPES_USED] [static] |
Definition at line 87 of file timing_place_lookup.c.
t_type_ptr EMPTY_TYPE_BACKUP [static] |
Definition at line 85 of file timing_place_lookup.c.
t_type_ptr FILL_TYPE_BACKUP [static] |
Definition at line 86 of file timing_place_lookup.c.
struct s_grid_tile** grid_backup [static] |
Definition at line 89 of file timing_place_lookup.c.
t_type_ptr IO_TYPE_BACKUP [static] |
Definition at line 84 of file timing_place_lookup.c.
float** net_delay [static] |
Definition at line 79 of file timing_place_lookup.c.
float** net_slack [static] |
Definition at line 80 of file timing_place_lookup.c.
int num_types_backup [static] |
Definition at line 90 of file timing_place_lookup.c.
float* pin_criticality [static] |
Definition at line 81 of file timing_place_lookup.c.
t_rt_node** rt_node_of_sink [static] |
Definition at line 83 of file timing_place_lookup.c.
int* sink_order [static] |
Definition at line 82 of file timing_place_lookup.c.
t_type_descriptor* type_descriptors_backup [static] |
Definition at line 88 of file timing_place_lookup.c.