#include <math.h>
#include "util.h"
#include "vpr_types.h"
#include "globals.h"
#include "rr_graph_util.h"
#include "rr_graph2.h"
#include "rr_graph_indexed_data.h"
Go to the source code of this file.
Functions | |
static void | load_rr_indexed_data_base_costs (int nodes_per_chan, t_ivec ***rr_node_indices, enum e_base_cost_type base_cost_type, int wire_to_ipin_switch) |
static float | get_delay_normalization_fac (int nodes_per_chan, t_ivec ***rr_node_indices) |
static float | get_average_opin_delay (t_ivec ***rr_node_indices, int nodes_per_chan) |
static void | load_rr_indexed_data_T_values (int index_start, int num_indices_to_load, t_rr_type rr_type, int nodes_per_chan, t_ivec ***rr_node_indices, t_segment_inf *segment_inf) |
void | alloc_and_load_rr_indexed_data (IN t_segment_inf *segment_inf, IN int num_segment, IN t_ivec ***rr_node_indices, IN int nodes_per_chan, int wire_to_ipin_switch, enum e_base_cost_type base_cost_type) |
void alloc_and_load_rr_indexed_data | ( | IN t_segment_inf * | segment_inf, | |
IN int | num_segment, | |||
IN t_ivec *** | rr_node_indices, | |||
IN int | nodes_per_chan, | |||
int | wire_to_ipin_switch, | |||
enum e_base_cost_type | base_cost_type | |||
) |
Definition at line 49 of file rr_graph_indexed_data.c.
00055 { 00056 00057 int iseg, length, i, index; 00058 00059 num_rr_indexed_data = CHANX_COST_INDEX_START + (2 * num_segment); 00060 rr_indexed_data = (t_rr_indexed_data *) my_malloc(num_rr_indexed_data * 00061 sizeof 00062 (t_rr_indexed_data)); 00063 00064 /* For rr_types that aren't CHANX or CHANY, base_cost is valid, but most * 00065 * * other fields are invalid. For IPINs, the T_linear field is also valid; * 00066 * * all other fields are invalid. For SOURCES, SINKs and OPINs, all fields * 00067 * * other than base_cost are invalid. Mark invalid fields as OPEN for safety. */ 00068 00069 for(i = SOURCE_COST_INDEX; i <= IPIN_COST_INDEX; i++) 00070 { 00071 rr_indexed_data[i].ortho_cost_index = OPEN; 00072 rr_indexed_data[i].seg_index = OPEN; 00073 rr_indexed_data[i].inv_length = OPEN; 00074 rr_indexed_data[i].T_linear = OPEN; 00075 rr_indexed_data[i].T_quadratic = OPEN; 00076 rr_indexed_data[i].C_load = OPEN; 00077 } 00078 00079 rr_indexed_data[IPIN_COST_INDEX].T_linear = 00080 switch_inf[wire_to_ipin_switch].Tdel; 00081 00082 /* X-directed segments. */ 00083 00084 for(iseg = 0; iseg < num_segment; iseg++) 00085 { 00086 index = CHANX_COST_INDEX_START + iseg; 00087 00088 rr_indexed_data[index].ortho_cost_index = index + num_segment; 00089 00090 if(segment_inf[iseg].longline) 00091 length = nx; 00092 else 00093 length = min(segment_inf[iseg].length, nx); 00094 00095 00096 rr_indexed_data[index].inv_length = 1. / length; 00097 rr_indexed_data[index].seg_index = iseg; 00098 } 00099 00100 load_rr_indexed_data_T_values(CHANX_COST_INDEX_START, num_segment, 00101 CHANX, nodes_per_chan, rr_node_indices, 00102 segment_inf); 00103 00104 /* Y-directed segments. */ 00105 00106 for(iseg = 0; iseg < num_segment; iseg++) 00107 { 00108 index = CHANX_COST_INDEX_START + num_segment + iseg; 00109 00110 rr_indexed_data[index].ortho_cost_index = index - num_segment; 00111 00112 if(segment_inf[iseg].longline) 00113 length = ny; 00114 else 00115 length = min(segment_inf[iseg].length, ny); 00116 00117 rr_indexed_data[index].inv_length = 1. / length; 00118 rr_indexed_data[index].seg_index = iseg; 00119 } 00120 00121 load_rr_indexed_data_T_values((CHANX_COST_INDEX_START + num_segment), 00122 num_segment, CHANY, nodes_per_chan, 00123 rr_node_indices, segment_inf); 00124 00125 load_rr_indexed_data_base_costs(nodes_per_chan, rr_node_indices, 00126 base_cost_type, wire_to_ipin_switch); 00127 00128 }
static float get_average_opin_delay | ( | t_ivec *** | rr_node_indices, | |
int | nodes_per_chan | |||
) | [static] |
Definition at line 257 of file rr_graph_indexed_data.c.
00259 { 00260 00261 /* Returns the average delay from an OPIN to a wire in an adjacent channel. */ 00262 /* RESEARCH TODO: Got to think if this heuristic needs to change for hetero, right now, I'll calculate 00263 * the average delay of non-IO blocks */ 00264 int inode, ipin, iclass, iedge, itype, num_edges, to_switch, to_node, 00265 num_conn; 00266 float Cload, Tdel; 00267 00268 Tdel = 0.; 00269 num_conn = 0; 00270 for(itype = 0; 00271 itype < num_types && &type_descriptors[itype] != IO_TYPE; itype++) 00272 { 00273 for(ipin = 0; ipin < type_descriptors[itype].num_pins; ipin++) 00274 { 00275 iclass = type_descriptors[itype].pin_class[ipin]; 00276 if(type_descriptors[itype].class_inf[iclass].type == 00277 DRIVER) 00278 { /* OPIN */ 00279 inode = 00280 get_rr_node_index((nx + 1) / 2, (ny + 1) / 2, 00281 OPIN, ipin, 00282 rr_node_indices); 00283 num_edges = rr_node[inode].num_edges; 00284 00285 for(iedge = 0; iedge < num_edges; iedge++) 00286 { 00287 to_node = rr_node[inode].edges[iedge]; 00288 to_switch = 00289 rr_node[inode].switches[iedge]; 00290 Cload = rr_node[to_node].C; 00291 Tdel += 00292 Cload * switch_inf[to_switch].R + 00293 switch_inf[to_switch].Tdel; 00294 num_conn++; 00295 } 00296 } 00297 } 00298 } 00299 00300 Tdel /= (float)num_conn; 00301 return (Tdel); 00302 }
static float get_delay_normalization_fac | ( | int | nodes_per_chan, | |
t_ivec *** | rr_node_indices | |||
) | [static] |
Definition at line 213 of file rr_graph_indexed_data.c.
00215 { 00216 00217 /* Returns the average delay to go 1 FB distance along a wire. */ 00218 00219 const int clb_dist = 3; /* Number of CLBs I think the average conn. goes. */ 00220 00221 int inode, itrack, cost_index; 00222 float Tdel, Tdel_sum, frac_num_seg; 00223 00224 Tdel_sum = 0.; 00225 00226 for(itrack = 0; itrack < nodes_per_chan; itrack++) 00227 { 00228 inode = 00229 get_rr_node_index((nx + 1) / 2, (ny + 1) / 2, CHANX, itrack, 00230 rr_node_indices); 00231 cost_index = rr_node[inode].cost_index; 00232 frac_num_seg = clb_dist * rr_indexed_data[cost_index].inv_length; 00233 Tdel = frac_num_seg * rr_indexed_data[cost_index].T_linear + 00234 frac_num_seg * frac_num_seg * 00235 rr_indexed_data[cost_index].T_quadratic; 00236 Tdel_sum += Tdel / (float)clb_dist; 00237 } 00238 00239 for(itrack = 0; itrack < nodes_per_chan; itrack++) 00240 { 00241 inode = 00242 get_rr_node_index((nx + 1) / 2, (ny + 1) / 2, CHANY, itrack, 00243 rr_node_indices); 00244 cost_index = rr_node[inode].cost_index; 00245 frac_num_seg = clb_dist * rr_indexed_data[cost_index].inv_length; 00246 Tdel = frac_num_seg * rr_indexed_data[cost_index].T_linear + 00247 frac_num_seg * frac_num_seg * 00248 rr_indexed_data[cost_index].T_quadratic; 00249 Tdel_sum += Tdel / (float)clb_dist; 00250 } 00251 00252 return (Tdel_sum / (2. * nodes_per_chan)); 00253 }
static void load_rr_indexed_data_base_costs | ( | int | nodes_per_chan, | |
t_ivec *** | rr_node_indices, | |||
enum e_base_cost_type | base_cost_type, | |||
int | wire_to_ipin_switch | |||
) | [static] |
Definition at line 132 of file rr_graph_indexed_data.c.
00136 { 00137 00138 /* Loads the base_cost member of rr_indexed_data according to the specified * 00139 * base_cost_type. */ 00140 00141 float delay_normalization_fac; 00142 int index; 00143 00144 if(base_cost_type == DELAY_NORMALIZED) 00145 { 00146 delay_normalization_fac = 00147 get_delay_normalization_fac(nodes_per_chan, rr_node_indices); 00148 } 00149 else 00150 { 00151 delay_normalization_fac = 1.; 00152 } 00153 00154 if(base_cost_type == DEMAND_ONLY || base_cost_type == DELAY_NORMALIZED) 00155 { 00156 rr_indexed_data[SOURCE_COST_INDEX].base_cost = 00157 delay_normalization_fac; 00158 rr_indexed_data[SINK_COST_INDEX].base_cost = 0.; 00159 rr_indexed_data[OPIN_COST_INDEX].base_cost = 00160 delay_normalization_fac; 00161 00162 #ifndef SPEC 00163 rr_indexed_data[IPIN_COST_INDEX].base_cost = 00164 0.95 * delay_normalization_fac; 00165 #else /* Avoid roundoff for SPEC */ 00166 rr_indexed_data[IPIN_COST_INDEX].base_cost = 00167 delay_normalization_fac; 00168 #endif 00169 } 00170 00171 else if(base_cost_type == INTRINSIC_DELAY) 00172 { 00173 rr_indexed_data[SOURCE_COST_INDEX].base_cost = 0.; 00174 rr_indexed_data[SINK_COST_INDEX].base_cost = 0.; 00175 rr_indexed_data[OPIN_COST_INDEX].base_cost = 00176 get_average_opin_delay(rr_node_indices, nodes_per_chan); 00177 rr_indexed_data[IPIN_COST_INDEX].base_cost = 00178 switch_inf[wire_to_ipin_switch].Tdel; 00179 } 00180 00181 /* Load base costs for CHANX and CHANY segments */ 00182 00183 for(index = CHANX_COST_INDEX_START; index < num_rr_indexed_data; index++) 00184 { 00185 if(base_cost_type == INTRINSIC_DELAY) 00186 rr_indexed_data[index].base_cost = 00187 rr_indexed_data[index].T_linear + 00188 rr_indexed_data[index].T_quadratic; 00189 else 00190 /* rr_indexed_data[index].base_cost = delay_normalization_fac / 00191 rr_indexed_data[index].inv_length; */ 00192 00193 rr_indexed_data[index].base_cost = delay_normalization_fac; 00194 /* rr_indexed_data[index].base_cost = delay_normalization_fac * 00195 sqrt (1. / rr_indexed_data[index].inv_length); */ 00196 /* rr_indexed_data[index].base_cost = delay_normalization_fac * 00197 (1. + 1. / rr_indexed_data[index].inv_length); */ 00198 } 00199 00200 /* Save a copy of the base costs -- if dynamic costing is used by the * 00201 * router, the base_cost values will get changed all the time and being * 00202 * able to restore them from a saved version is useful. */ 00203 00204 for(index = 0; index < num_rr_indexed_data; index++) 00205 { 00206 rr_indexed_data[index].saved_base_cost = 00207 rr_indexed_data[index].base_cost; 00208 } 00209 }
static void load_rr_indexed_data_T_values | ( | int | index_start, | |
int | num_indices_to_load, | |||
t_rr_type | rr_type, | |||
int | nodes_per_chan, | |||
t_ivec *** | rr_node_indices, | |||
t_segment_inf * | segment_inf | |||
) | [static] |
Definition at line 306 of file rr_graph_indexed_data.c.
00312 { 00313 00314 /* Loads the average propagation times through segments of each index type * 00315 * for either all CHANX segment types or all CHANY segment types. It does * 00316 * this by looking at all the segments in one channel in the middle of the * 00317 * array and averaging the R and C values of all segments of the same type * 00318 * and using them to compute average delay values for this type of segment. */ 00319 00320 int itrack, iseg, inode, cost_index, iswitch; 00321 float *C_total, *R_total; /* [0..num_rr_indexed_data - 1] */ 00322 int *num_nodes_of_index; /* [0..num_rr_indexed_data - 1] */ 00323 float Rnode, Cnode, Rsw, Tsw; 00324 00325 num_nodes_of_index = (int *)my_calloc(num_rr_indexed_data, sizeof(int)); 00326 C_total = (float *)my_calloc(num_rr_indexed_data, sizeof(float)); 00327 R_total = (float *)my_calloc(num_rr_indexed_data, sizeof(float)); 00328 00329 /* Get average C and R values for all the segments of this type in one * 00330 * channel segment, near the middle of the array. */ 00331 00332 for(itrack = 0; itrack < nodes_per_chan; itrack++) 00333 { 00334 inode = 00335 get_rr_node_index((nx + 1) / 2, (ny + 1) / 2, rr_type, itrack, 00336 rr_node_indices); 00337 cost_index = rr_node[inode].cost_index; 00338 num_nodes_of_index[cost_index]++; 00339 C_total[cost_index] += rr_node[inode].C; 00340 R_total[cost_index] += rr_node[inode].R; 00341 } 00342 00343 00344 for(cost_index = index_start; 00345 cost_index < index_start + num_indices_to_load; cost_index++) 00346 { 00347 00348 if(num_nodes_of_index[cost_index] == 0) 00349 { /* Segments don't exist. */ 00350 rr_indexed_data[cost_index].T_linear = OPEN; 00351 rr_indexed_data[cost_index].T_quadratic = OPEN; 00352 rr_indexed_data[cost_index].C_load = OPEN; 00353 } 00354 else 00355 { 00356 Rnode = 00357 R_total[cost_index] / num_nodes_of_index[cost_index]; 00358 Cnode = 00359 C_total[cost_index] / num_nodes_of_index[cost_index]; 00360 iseg = rr_indexed_data[cost_index].seg_index; 00361 iswitch = segment_inf[iseg].wire_switch; 00362 Rsw = switch_inf[iswitch].R; 00363 Tsw = switch_inf[iswitch].Tdel; 00364 00365 if(switch_inf[iswitch].buffered) 00366 { 00367 rr_indexed_data[cost_index].T_linear = 00368 Tsw + Rsw * Cnode + 0.5 * Rnode * Cnode; 00369 rr_indexed_data[cost_index].T_quadratic = 0.; 00370 rr_indexed_data[cost_index].C_load = 0.; 00371 } 00372 else 00373 { /* Pass transistor */ 00374 rr_indexed_data[cost_index].C_load = Cnode; 00375 00376 /* See Dec. 23, 1997 notes for deriviation of formulae. */ 00377 00378 rr_indexed_data[cost_index].T_linear = 00379 Tsw + 0.5 * Rsw * Cnode; 00380 rr_indexed_data[cost_index].T_quadratic = 00381 (Rsw + Rnode) * 0.5 * Cnode; 00382 } 00383 } 00384 } 00385 00386 free(num_nodes_of_index); 00387 free(C_total); 00388 free(R_total); 00389 }