#include #include #include "util.h" #include "vpr_types.h" #include "globals.h" #include "path_delay.h" #include "path_delay2.h" #include "net_delay.h" #include "timing_place_lookup.h" #include "timing_place.h" float **timing_place_crit; /*available externally */ static t_chunk timing_place_crit_ch = {NULL, 0, NULL}; static t_chunk net_delay_ch = {NULL, 0, NULL}; /*static struct s_linked_vptr *timing_place_crit_chunk_list_head; static struct s_linked_vptr *net_delay_chunk_list_head;*/ /******** prototypes ******************/ /*static float **alloc_crit(struct s_linked_vptr **chunk_list_head_ptr); static void free_crit(struct s_linked_vptr **chunk_list_head_ptr);*/ static float **alloc_crit(t_chunk *chunk_list_ptr); static void free_crit(t_chunk *chunk_list_ptr); /**************************************/ static float ** alloc_crit(t_chunk *chunk_list_ptr) { /* Allocates space for the timing_place_crit data structure * * [0..num_nets-1][1..num_pins-1]. I chunk the data to save space on large * * problems. */ float **local_crit; /* [0..num_nets-1][1..num_pins-1] */ float *tmp_ptr; int inet; local_crit = (float **) my_malloc(num_nets * sizeof(float *)); for (inet = 0; inet < num_nets; inet++) { tmp_ptr = (float *) my_chunk_malloc( (clb_net[inet].num_sinks) * sizeof(float), chunk_list_ptr); local_crit[inet] = tmp_ptr - 1; /* [1..num_sinks] */ } return (local_crit); } /**************************************/ static void free_crit(t_chunk *chunk_list_ptr){ free_chunk_memory(chunk_list_ptr); } /**************************************/ void print_sink_delays(const char *fname) { int num_at_level, num_edges, inode, ilevel, i; FILE *fp; fp = my_fopen(fname, "w", 0); for (ilevel = num_tnode_levels - 1; ilevel >= 0; ilevel--) { num_at_level = tnodes_at_level[ilevel].nelem; for (i = 0; i < num_at_level; i++) { inode = tnodes_at_level[ilevel].list[i]; num_edges = tnode[inode].num_edges; if (num_edges == 0) { /* sink */ fprintf(fp, "%g\n", tnode[inode].T_arr); } } } fclose(fp); } /**************************************/ void load_criticalities(t_slack * slacks, float crit_exponent) { /* Performs a 1-to-1 mapping from criticality to timing_place_crit. For every pin on every net (or, equivalently, for every tedge ending in that pin), timing_place_crit = criticality^(criticality exponent) */ int inet, ipin; #ifdef PATH_COUNTING float timing_criticality, path_criticality; #endif for (inet = 0; inet < num_nets; inet++) { if (inet == OPEN) continue; if (clb_net[inet].is_global) continue; for (ipin = 1; ipin <= clb_net[inet].num_sinks; ipin++) { if (slacks->timing_criticality[inet][ipin] < HUGE_NEGATIVE_FLOAT + 1) { /* We didn't analyze this connection, so give it a timing_place_crit of 0. */ timing_place_crit[inet][ipin] = 0.; } else { #ifdef PATH_COUNTING /* Calculate criticality as a weighted sum of timing criticality and path criticality. The placer likes a great deal of contrast between criticalities. Since path criticality varies much more than timing, we "sharpen" timing criticality by taking it to some power, crit_exponent (between 1 and 8 by default). */ path_criticality = slacks->path_criticality[inet][ipin]; timing_criticality = pow(slacks->timing_criticality[inet][ipin], crit_exponent); timing_place_crit[inet][ipin] = PLACE_PATH_WEIGHT * path_criticality + (1 - PLACE_PATH_WEIGHT) * timing_criticality; #else /* Just take timing criticality to some power (crit_exponent). */ timing_place_crit[inet][ipin] = pow(slacks->timing_criticality[inet][ipin], crit_exponent); #endif } } } } /**************************************/ 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) { t_slack * slacks = alloc_and_load_timing_graph(timing_inf); (*net_delay) = alloc_net_delay(&net_delay_ch, clb_net, num_nets); compute_delay_lookup_tables(router_opts, det_routing_arch, segment_inf, timing_inf, chan_width_dist, directs, num_directs); timing_place_crit = alloc_crit(&timing_place_crit_ch); return slacks; } /**************************************/ void free_lookups_and_criticalities(float ***net_delay, t_slack * slacks) { free(timing_place_crit); free_crit(&timing_place_crit_ch); free_timing_graph(slacks); free_net_delay(*net_delay, &net_delay_ch); free_place_lookup_structs(); } /**************************************/