VPR-6.0

vpr/SRC/place/timing_place.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <math.h>
00003 #include "util.h"
00004 #include "vpr_types.h"
00005 #include "globals.h"
00006 #include "path_delay.h"
00007 #include "path_delay2.h"
00008 #include "net_delay.h"
00009 #include "timing_place_lookup.h"
00010 #include "timing_place.h"
00011 
00012 
00013 float **timing_place_crit;      /**< available externally */
00014 
00015 static struct s_linked_vptr *timing_place_crit_chunk_list_head;
00016 static struct s_linked_vptr *net_delay_chunk_list_head;
00017 
00018 
00019 /******** prototypes ******************/
00020 static float **alloc_crit(struct s_linked_vptr **chunk_list_head_ptr);
00021 
00022 static void free_crit(struct s_linked_vptr **chunk_list_head_ptr);
00023 
00024 /**************************************/
00025 
00026 /** Allocates space for the timing_place_crit data structure 
00027  * [0..num_nets-1][1..num_pins-1].  I chunk the data to save space on large    
00028  * problems.                                                                   
00029  */
00030 static float **
00031 alloc_crit(struct s_linked_vptr **chunk_list_head_ptr)
00032 {
00033 
00034     float **local_crit;         /* [0..num_nets-1][1..num_pins-1] */
00035     float *tmp_ptr;
00036     int inet;
00037     int chunk_bytes_avail;
00038     char *chunk_next_avail_mem;
00039 
00040     *chunk_list_head_ptr = NULL;
00041     chunk_bytes_avail = 0;
00042     chunk_next_avail_mem = NULL;
00043 
00044     local_crit = (float **)my_malloc(num_nets * sizeof(float *));
00045 
00046     for(inet = 0; inet < num_nets; inet++)
00047         {
00048             tmp_ptr = (float *)my_chunk_malloc((clb_net[inet].num_sinks) *
00049                                                sizeof(float),
00050                                                chunk_list_head_ptr,
00051                                                &chunk_bytes_avail,
00052                                                &chunk_next_avail_mem);
00053             local_crit[inet] = tmp_ptr - 1;     /* [1..num_sinks] */
00054         }
00055 
00056     return (local_crit);
00057 }
00058 
00059 /**************************************/
00060 static void
00061 free_crit(struct s_linked_vptr **chunk_list_head_ptr)
00062 {
00063 
00064     free_chunk_memory(*chunk_list_head_ptr);
00065     *chunk_list_head_ptr = NULL;
00066 }
00067 
00068 /**************************************/
00069 void
00070 print_sink_delays(char *fname)
00071 {
00072 
00073 
00074     int num_at_level, num_edges, inode, ilevel, i;
00075     FILE *fp;
00076 
00077     fp = my_fopen(fname, "w", 0);
00078 
00079 
00080     for(ilevel = num_tnode_levels - 1; ilevel >= 0; ilevel--)
00081         {
00082             num_at_level = tnodes_at_level[ilevel].nelem;
00083 
00084             for(i = 0; i < num_at_level; i++)
00085                 {
00086                     inode = tnodes_at_level[ilevel].list[i];
00087                     num_edges = tnode[inode].num_edges;
00088 
00089                     if(num_edges == 0)
00090                         {       /* sink */
00091                             fprintf(fp, "%g\n", tnode[inode].T_arr);
00092                         }
00093                 }
00094         }
00095     fclose(fp);
00096 }
00097 
00098 /**************************************/
00099 /** set criticality values, returns the maximum criticality found */
00100 /** assumes that net_slack contains correct values, ie. assumes  
00101  * that load_net_slack has been called
00102  */
00103 void
00104 load_criticalities(struct s_placer_opts placer_opts,
00105                    float **net_slack,
00106                    float d_max,
00107                    float crit_exponent)
00108 {
00109 
00110     int inet, ipin;
00111     float pin_crit;
00112 
00113 
00114 
00115     for(inet = 0; inet < num_nets; inet++)
00116         {
00117 
00118             if(inet == OPEN)
00119                 continue;
00120             if(clb_net[inet].is_global)
00121                 continue;
00122 
00123             for(ipin = 1; ipin <= clb_net[inet].num_sinks; ipin++)
00124                 {
00125                     /*clip the criticality to never go negative (could happen */
00126                     /*for a constant generator since it's slack is huge) */
00127                     pin_crit = max(1 - net_slack[inet][ipin] / d_max, 0.);
00128                     timing_place_crit[inet][ipin] =
00129                         pow(pin_crit, crit_exponent);
00130 
00131                 }
00132         }
00133 }
00134 
00135 /**************************************/
00136 
00137 void
00138 alloc_lookups_and_criticalities(t_chan_width_dist chan_width_dist,
00139                                 struct s_router_opts router_opts,
00140                                 struct s_det_routing_arch det_routing_arch,
00141                                 t_segment_inf * segment_inf,
00142                                 t_timing_inf timing_inf,
00143                                 float ***net_delay,
00144                                 float ***net_slack)
00145 {
00146 
00147     (*net_slack) = alloc_and_load_timing_graph(timing_inf);
00148 
00149     (*net_delay) = alloc_net_delay(&net_delay_chunk_list_head, clb_net, num_nets);
00150 
00151     compute_delay_lookup_tables(router_opts, det_routing_arch, segment_inf,
00152                                 timing_inf, chan_width_dist);
00153 
00154     timing_place_crit = alloc_crit(&timing_place_crit_chunk_list_head);
00155 
00156 }
00157 
00158 /**************************************/
00159 void
00160 free_lookups_and_criticalities(float ***net_delay,
00161                                float ***net_slack)
00162 {
00163 
00164     free(timing_place_crit);
00165     free_crit(&timing_place_crit_chunk_list_head);
00166 
00167     free_timing_graph(*net_slack);
00168     free_net_delay(*net_delay, &net_delay_chunk_list_head);
00169 
00170 }
00171 
00172 /**************************************/