Go to the source code of this file.
Data Structures | |
struct | t_tedge |
struct | t_tnode |
struct | t_tnode_descript |
Enumerations | |
enum | t_tnode_type { INPAD_SOURCE, INPAD_OPIN, OUTPAD_IPIN, OUTPAD_SINK, FB_IPIN, FB_OPIN, SUBBLK_IPIN, SUBBLK_OPIN, FF_SINK, FF_SOURCE, CONSTANT_GEN_SOURCE } |
Functions | |
int | alloc_and_load_timing_graph_levels (void) |
void | check_timing_graph (int num_const_gen, int num_ff, int num_sinks) |
float | print_critical_path_node (FILE *fp, t_linked_int *critical_path_node, t_subblock_data subblock_data) |
Variables | |
t_tnode * | tnode |
t_tnode_descript * | tnode_descript |
int | num_tnodes |
int * | net_to_driver_tnode |
struct s_ivec * | tnodes_at_level |
int | num_tnode_levels |
enum t_tnode_type |
INPAD_SOURCE | |
INPAD_OPIN | |
OUTPAD_IPIN | |
OUTPAD_SINK | |
FB_IPIN | |
FB_OPIN | |
SUBBLK_IPIN | |
SUBBLK_OPIN | |
FF_SINK | |
FF_SOURCE | |
CONSTANT_GEN_SOURCE |
Definition at line 35 of file path_delay2.h.
00036 { INPAD_SOURCE, INPAD_OPIN, OUTPAD_IPIN, OUTPAD_SINK, 00037 FB_IPIN, FB_OPIN, SUBBLK_IPIN, SUBBLK_OPIN, FF_SINK, FF_SOURCE, 00038 CONSTANT_GEN_SOURCE 00039 }
int alloc_and_load_timing_graph_levels | ( | void | ) |
Definition at line 104 of file path_delay2.c.
00105 { 00106 00107 /* Does a breadth-first search through the timing graph in order to levelize * 00108 * it. This allows subsequent breadth-first traversals to be faster. Also * 00109 * returns the number of sinks in the graph (nodes with no fanout). */ 00110 00111 t_linked_int *free_list_head, *nodes_at_level_head; 00112 int inode, num_at_level, iedge, to_node, num_edges, num_sinks, 00113 num_levels, i; 00114 t_tedge *tedge; 00115 00116 /* [0..num_tnodes-1]. # of in-edges to each tnode that have not yet been * 00117 * seen in this traversal. */ 00118 00119 int *tnode_fanin_left; 00120 00121 00122 tnode_fanin_left = alloc_and_load_tnode_fanin_and_check_edges(&num_sinks); 00123 00124 free_list_head = NULL; 00125 nodes_at_level_head = NULL; 00126 00127 /* Very conservative -> max number of levels = num_tnodes. Realloc later. * 00128 * Temporarily need one extra level on the end because I look at the first * 00129 * empty level. */ 00130 00131 tnodes_at_level = (struct s_ivec *)my_malloc((num_tnodes + 1) * 00132 sizeof(struct s_ivec)); 00133 00134 /* Scan through the timing graph, putting all the primary input nodes (no * 00135 * fanin) into level 0 of the level structure. */ 00136 00137 num_at_level = 0; 00138 00139 for(inode = 0; inode < num_tnodes; inode++) 00140 { 00141 if(tnode_fanin_left[inode] == 0) 00142 { 00143 num_at_level++; 00144 nodes_at_level_head = 00145 insert_in_int_list(nodes_at_level_head, inode, 00146 &free_list_head); 00147 } 00148 } 00149 00150 alloc_ivector_and_copy_int_list(&nodes_at_level_head, num_at_level, 00151 &tnodes_at_level[0], &free_list_head); 00152 00153 num_levels = 0; 00154 00155 while(num_at_level != 0) 00156 { /* Until there's nothing in the queue. */ 00157 num_levels++; 00158 num_at_level = 0; 00159 00160 for(i = 0; i < tnodes_at_level[num_levels - 1].nelem; i++) 00161 { 00162 inode = tnodes_at_level[num_levels - 1].list[i]; 00163 tedge = tnode[inode].out_edges; 00164 num_edges = tnode[inode].num_edges; 00165 00166 for(iedge = 0; iedge < num_edges; iedge++) 00167 { 00168 to_node = tedge[iedge].to_node; 00169 tnode_fanin_left[to_node]--; 00170 00171 if(tnode_fanin_left[to_node] == 0) 00172 { 00173 num_at_level++; 00174 nodes_at_level_head = 00175 insert_in_int_list 00176 (nodes_at_level_head, to_node, 00177 &free_list_head); 00178 } 00179 } 00180 } 00181 00182 alloc_ivector_and_copy_int_list(&nodes_at_level_head, 00183 num_at_level, 00184 &tnodes_at_level[num_levels], 00185 &free_list_head); 00186 } 00187 00188 tnodes_at_level = 00189 (struct s_ivec *)my_realloc(tnodes_at_level, 00190 num_levels * sizeof(struct s_ivec)); 00191 num_tnode_levels = num_levels; 00192 00193 free(tnode_fanin_left); 00194 free_int_list(&free_list_head); 00195 return (num_sinks); 00196 }
void check_timing_graph | ( | int | num_const_gen, | |
int | num_ff, | |||
int | num_sinks | |||
) |
Definition at line 200 of file path_delay2.c.
00203 { 00204 00205 /* Checks the timing graph to see that: (1) all the tnodes have been put * 00206 * into some level of the timing graph; (2) the number of primary inputs * 00207 * to the timing graph is equal to the number of input pads + the number of * 00208 * constant generators; and (3) the number of sinks (nodes with no fanout) * 00209 * equals the number of output pads + the number of flip flops. */ 00210 00211 int i, j, num_tnodes_check, ilevel, inet, inode, error, num_p_inputs, 00212 num_p_outputs; 00213 00214 error = 0; 00215 num_tnodes_check = 0; 00216 num_p_inputs = 0; 00217 num_p_outputs = 0; 00218 00219 /* Count I/O input and output pads */ 00220 for(i = 0; i < num_blocks; i++) 00221 { 00222 if(block[i].type == IO_TYPE) 00223 { 00224 for(j = 0; j < IO_TYPE->num_pins; j++) 00225 { 00226 if(block[i].nets[j] != OPEN) 00227 { 00228 if(IO_TYPE-> 00229 class_inf[IO_TYPE->pin_class[j]]. 00230 type == DRIVER) 00231 { 00232 num_p_inputs++; 00233 } 00234 else 00235 { 00236 assert(IO_TYPE-> 00237 class_inf[IO_TYPE-> 00238 pin_class[j]]. 00239 type == RECEIVER); 00240 num_p_outputs++; 00241 } 00242 } 00243 } 00244 } 00245 } 00246 00247 for(ilevel = 0; ilevel < num_tnode_levels; ilevel++) 00248 num_tnodes_check += tnodes_at_level[ilevel].nelem; 00249 00250 if(num_tnodes_check != num_tnodes) 00251 { 00252 printf 00253 ("Error in check_timing_graph: %d tnodes appear in the tnode level " 00254 "structure. Expected %d.\n", num_tnodes_check, num_tnodes); 00255 printf("Check the netlist for combinational cycles.\n"); 00256 error++; 00257 } 00258 00259 if(num_const_gen + num_p_inputs != tnodes_at_level[0].nelem) 00260 { 00261 printf 00262 ("Error in check_timing_graph: %d tnodes are sources (have no " 00263 "inputs -- expected %d.\n", tnodes_at_level[0].nelem, 00264 num_const_gen + num_p_inputs); 00265 error++; 00266 } 00267 00268 if(num_sinks != num_p_outputs + num_ff) 00269 { 00270 printf 00271 ("Error in check_timing_graph: %d tnodes are sinks (have no " 00272 "outputs -- expected %d.\n", num_sinks, 00273 num_ff + num_p_outputs); 00274 error++; 00275 } 00276 00277 for(inet = 0; inet < num_nets; inet++) 00278 { 00279 inode = net_to_driver_tnode[inet]; 00280 if(inode < 0 || inode >= num_tnodes) 00281 { 00282 printf("Error in check_timing_graph:\n" 00283 "\tdriver of net %d has a tnode mapping of %d (out of range).\n", 00284 inet, inode); 00285 error++; 00286 } 00287 } 00288 00289 if(error != 0) 00290 { 00291 printf("Found %d Errors in the timing graph. Aborting.\n", 00292 error); 00293 exit(1); 00294 } 00295 }
float print_critical_path_node | ( | FILE * | fp, | |
t_linked_int * | critical_path_node, | |||
t_subblock_data | subblock_data | |||
) |
Definition at line 299 of file path_delay2.c.
00302 { 00303 00304 /* Prints one tnode on the critical path out to fp. Returns the delay to * 00305 * the next node. */ 00306 00307 int inode, iblk, ipin, inet, downstream_node; 00308 t_tnode_type type; 00309 static char *tnode_type_names[] = { "INPAD_SOURCE", "INPAD_OPIN", 00310 "OUTPAD_IPIN", "OUTPAD_SINK", "CLB_IPIN", "CLB_OPIN", 00311 "SUBBLK_IPIN", "SUBBLK_OPIN", "FF_SINK", "FF_SOURCE", 00312 "CONSTANT_GEN_SOURCE" 00313 }; /* NB: static for speed */ 00314 t_linked_int *next_crit_node; 00315 float Tdel; 00316 00317 inode = critical_path_node->data; 00318 type = tnode_descript[inode].type; 00319 iblk = tnode_descript[inode].iblk; 00320 ipin = tnode_descript[inode].ipin; 00321 00322 fprintf(fp, "Node: %d %s Block #%d (%s)\n", inode, 00323 tnode_type_names[type], iblk, block[iblk].name); 00324 00325 if(type != INPAD_SOURCE && type != OUTPAD_SINK && type != FF_SINK && 00326 type != FF_SOURCE && type != CONSTANT_GEN_SOURCE) 00327 { 00328 fprintf(fp, "Pin: %d ", ipin); 00329 } 00330 00331 if(type == SUBBLK_IPIN || type == SUBBLK_OPIN || type == FF_SINK 00332 || type == FF_SOURCE || type == CONSTANT_GEN_SOURCE) 00333 { 00334 fprintf(fp, "Subblock #%d subpin #%d", 00335 tnode_descript[inode].isubblk, 00336 tnode_descript[inode].ipin); 00337 } 00338 00339 if(type != INPAD_SOURCE && type != OUTPAD_SINK) 00340 { 00341 fprintf(fp, "\n"); 00342 } 00343 00344 fprintf(fp, "T_arr: %g T_req: %g ", tnode[inode].T_arr, 00345 tnode[inode].T_req); 00346 00347 next_crit_node = critical_path_node->next; 00348 if(next_crit_node != NULL) 00349 { 00350 downstream_node = next_crit_node->data; 00351 Tdel = tnode[downstream_node].T_arr - tnode[inode].T_arr; 00352 fprintf(fp, "Tdel: %g\n", Tdel); 00353 } 00354 else 00355 { /* last node, no Tdel. */ 00356 Tdel = 0.; 00357 fprintf(fp, "\n"); 00358 } 00359 00360 if(type == FB_OPIN) 00361 { 00362 inet = block[iblk].nets[ipin]; 00363 fprintf(fp, "Net to next node: #%d (%s). Pins on net: %d.\n", 00364 inet, net[inet].name, (net[inet].num_sinks + 1)); 00365 } 00366 00367 if(type == INPAD_OPIN) 00368 { 00369 ipin = 00370 subblock_data.subblock_inf[iblk][tnode_descript[inode]. 00371 isubblk].outputs[ipin]; 00372 inet = block[iblk].nets[ipin]; 00373 fprintf(fp, "Net to next node: #%d (%s). Pins on net: %d.\n", 00374 inet, net[inet].name, (net[inet].num_sinks + 1)); 00375 } 00376 00377 fprintf(fp, "\n"); 00378 return (Tdel); 00379 }
int* net_to_driver_tnode |
Definition at line 16 of file path_delay2.c.
int num_tnode_levels |
Definition at line 23 of file path_delay2.c.
int num_tnodes |
Definition at line 12 of file path_delay2.c.
Definition at line 10 of file path_delay2.c.
Definition at line 11 of file path_delay2.c.
struct s_ivec* tnodes_at_level |
Definition at line 22 of file path_delay2.c.