#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "types.h"
#include "globals.h"
#include "errors.h"
#include "netlist_utils.h"
#include "odin_util.h"
#include "netlist_stats.h"
#include "multipliers.h"
Go to the source code of this file.
Functions | |
void | depth_first_traverse_stats (FILE *out, short marker_value, netlist_t *netlist) |
void | depth_first_traversal_graphcrunch_stats (nnode_t *node, FILE *fp, int traverse_mark_number) |
void | display_per_node_stats (FILE *fp, netlist_t *netlist) |
void | display_node_stats (FILE *fp, nnode_t *node) |
void | calculate_avg_fanout (netlist_t *netlist) |
void | calculate_avg_fanin (netlist_t *netlist) |
int | num_fanouts_on_output_pin (nnode_t *node, int output_pin_idx) |
void | add_to_distribution (int **distrib_ptr, int *distrib_size, int new_element) |
void | calculate_combinational_shapes (netlist_t *netlist) |
void | netlist_stats (netlist_t *netlist, char *path, char *name) |
void add_to_distribution | ( | int ** | distrib_ptr, | |
int * | distrib_size, | |||
int | new_element | |||
) |
Definition at line 434 of file netlist_stats.c.
00435 { 00436 if (new_element < (*distrib_size)) 00437 { 00438 /* IF - the distribution is already big enough */ 00439 (*distrib_ptr)[new_element]++; 00440 } 00441 else 00442 { 00443 (*distrib_size)++; 00444 (*distrib_ptr) = (int*)realloc((*distrib_ptr), sizeof(int)*(new_element+1)); 00445 (*distrib_ptr)[new_element]++; 00446 } 00447 }
void calculate_avg_fanin | ( | netlist_t * | netlist | ) |
Definition at line 241 of file netlist_stats.c.
00242 { 00243 int i; 00244 long fanin_total = 0; 00245 00246 /* GND nnode_t *gnd_node;*/ 00247 00248 /* VCC nnode_t *vcc_node;*/ 00249 00250 /* PIs nnode_t** top_input_nodes; 00251 int num_top_input_nodes; */ 00252 00253 /* POs nnode_t** top_output_nodes; 00254 int num_top_output_nodes; */ 00255 fanin_total += netlist->num_top_output_nodes; 00256 for (i = 0; i < netlist->num_top_output_nodes; i++) 00257 { 00258 add_to_distribution(&netlist->stats->fanin_distribution, &netlist->stats->num_fanin_distribution, 1); 00259 } 00260 00261 /* FFs nnode_t** ff_nodes; 00262 int num_ff_nodes; */ 00263 fanin_total += netlist->num_ff_nodes; 00264 for (i = 0; i < netlist->num_ff_nodes; i++) 00265 { 00266 add_to_distribution(&netlist->stats->fanin_distribution, &netlist->stats->num_fanin_distribution, 1); 00267 } 00268 00269 /* COBINATIONAL nnode_t** internal_nodes; 00270 int num_internal_nodes; */ 00271 for (i = 0; i < netlist->num_internal_nodes; i++) 00272 { 00273 fanin_total += netlist->internal_nodes[i]->num_input_pins; 00274 /* fanin is number of input pins */ 00275 add_to_distribution(&netlist->stats->fanin_distribution, &netlist->stats->num_fanin_distribution, netlist->internal_nodes[i]->num_input_pins); 00276 } 00277 00278 /* CLOCKS nnode_t** clocks; 00279 int num_clocks; */ 00280 00281 /* calculate the arithmetic average */ 00282 netlist->stats->average_fanin = (float)(fanin_total)/(float)(netlist->num_top_output_nodes+netlist->num_ff_nodes+ netlist->num_internal_nodes); 00283 netlist->stats->num_edges_fi = fanin_total; 00284 }
void calculate_avg_fanout | ( | netlist_t * | netlist | ) |
Definition at line 163 of file netlist_stats.c.
00164 { 00165 int i, j; 00166 long fanout_total = 0; 00167 long node_fanout; 00168 long output_pins_total = 0; 00169 00170 /* GND nnode_t *gnd_node;*/ 00171 00172 /* VCC nnode_t *vcc_node;*/ 00173 00174 /* PIs nnode_t** top_input_nodes; 00175 int num_top_input_nodes; */ 00176 for (i = 0; i < netlist->num_top_input_nodes; i++) 00177 { 00178 if (netlist->top_input_nodes[i]->type == CLOCK_NODE) 00179 continue; 00180 00181 for (j = 0; j < netlist->top_input_nodes[i]->num_output_pins; j++) 00182 { 00183 node_fanout = num_fanouts_on_output_pin(netlist->top_input_nodes[i], j); 00184 if (node_fanout > 0) 00185 { 00186 output_pins_total ++; 00187 add_to_distribution(&netlist->stats->fanout_distribution, &netlist->stats->num_fanout_distribution, node_fanout); 00188 fanout_total += node_fanout; 00189 } 00190 } 00191 } 00192 00193 /* POs nnode_t** top_output_nodes; 00194 int num_top_output_nodes; */ 00195 00196 /* FFs nnode_t** ff_nodes; 00197 int num_ff_nodes; */ 00198 for (i = 0; i < netlist->num_ff_nodes; i++) 00199 { 00200 for (j = 0; j < netlist->ff_nodes[i]->num_output_pins; j++) 00201 { 00202 node_fanout = num_fanouts_on_output_pin(netlist->ff_nodes[i], j); 00203 if (node_fanout > 0) 00204 { 00205 output_pins_total ++; 00206 add_to_distribution(&netlist->stats->fanout_distribution, &netlist->stats->num_fanout_distribution, node_fanout); 00207 fanout_total += node_fanout; 00208 } 00209 } 00210 } 00211 00212 /* COBINATIONAL nnode_t** internal_nodes; 00213 int num_internal_nodes; */ 00214 for (i = 0; i < netlist->num_internal_nodes; i++) 00215 { 00216 for (j = 0; j < netlist->internal_nodes[i]->num_output_pins; j++) 00217 { 00218 node_fanout = num_fanouts_on_output_pin(netlist->internal_nodes[i], j); 00219 if (node_fanout > 0) 00220 { 00221 output_pins_total ++; 00222 add_to_distribution(&netlist->stats->fanout_distribution, &netlist->stats->num_fanout_distribution, node_fanout); 00223 fanout_total += node_fanout; 00224 } 00225 } 00226 } 00227 00228 /* CLOCKS nnode_t** clocks; 00229 int num_clocks; */ 00230 00231 /* calculate the arithmetic average */ 00232 netlist->stats->average_fanout = (float)(fanout_total)/(float)(output_pins_total); 00233 netlist->stats->num_edges_fo = fanout_total; 00234 netlist->stats->num_output_pins = output_pins_total; 00235 netlist->stats->average_output_pins_per_node = (float)output_pins_total/(float)(netlist->num_internal_nodes+netlist->num_ff_nodes+netlist->num_top_input_nodes); 00236 }
void calculate_combinational_shapes | ( | netlist_t * | netlist | ) |
Definition at line 292 of file netlist_stats.c.
00293 { 00294 int i; 00295 00296 netlist->stats->combinational_shape = (int **)malloc(sizeof(int*)*netlist->num_sequential_levels); 00297 netlist->stats->num_combinational_shape_for_sequential_level = (int *)malloc(sizeof(int)*netlist->num_sequential_levels); 00298 00299 /* initializ the shape records */ 00300 for (i = 0; i < netlist->num_sequential_levels; i++) 00301 { 00302 netlist->stats->num_combinational_shape_for_sequential_level = 0; 00303 netlist->stats->combinational_shape = NULL; 00304 } 00305 00306 /* COBINATIONAL nnode_t** internal_nodes; 00307 int num_internal_nodes; */ 00308 for (i = 0; i < netlist->num_internal_nodes; i++) 00309 { 00310 /* add the delay to the sequential level shape */ 00311 add_to_distribution(&netlist->stats->combinational_shape[netlist->internal_nodes[i]->sequential_level], &netlist->stats->num_combinational_shape_for_sequential_level[netlist->internal_nodes[i]->sequential_level], netlist->internal_nodes[i]->forward_level); 00312 } 00313 }
void depth_first_traversal_graphcrunch_stats | ( | nnode_t * | node, | |
FILE * | fp, | |||
int | traverse_mark_number | |||
) |
Definition at line 340 of file netlist_stats.c.
00341 { 00342 int i, j; 00343 nnode_t *next_node; 00344 nnet_t *next_net; 00345 00346 if (node->traverse_visited == traverse_mark_number) 00347 { 00348 return; 00349 } 00350 else 00351 { 00352 /* ELSE - this is a new node so depth visit it */ 00353 char *temp_string; 00354 char *temp_string2; 00355 00356 /* mark that we have visitied this node now */ 00357 node->traverse_visited = traverse_mark_number; 00358 00359 for (i = 0; i < node->num_output_pins; i++) 00360 { 00361 if (node->output_pins[i]->net == NULL) 00362 continue; 00363 00364 next_net = node->output_pins[i]->net; 00365 for (j = 0; j < next_net->num_fanout_pins; j++) 00366 { 00367 if (next_net->fanout_pins[j] == NULL) 00368 continue; 00369 00370 next_node = next_net->fanout_pins[j]->node; 00371 if (next_node == NULL) 00372 continue; 00373 00374 //temp_string = make_string_based_on_id(node); 00375 //temp_string2 = make_string_based_on_id(next_node); 00376 temp_string = make_simple_name(node->name, "^-+.", '_'); 00377 temp_string2 = make_simple_name(next_node->name, "^-+.", '_'); 00378 00379 if (node->type == OUTPUT_NODE) 00380 { 00381 /* renaming for output nodes */ 00382 temp_string = (char*)realloc(temp_string, sizeof(char)*strlen(temp_string)+1+2); 00383 sprintf(temp_string, "%s_O", temp_string); 00384 } 00385 if (next_node->type == OUTPUT_NODE) 00386 { 00387 /* renaming for output nodes */ 00388 temp_string2 = (char*)realloc(temp_string2, sizeof(char)*strlen(temp_string2)+1+2); 00389 sprintf(temp_string2, "%s_O", temp_string2); 00390 } 00391 00392 fprintf(fp, "%s\t%s\n", temp_string, temp_string2); 00393 00394 free(temp_string); 00395 free(temp_string2); 00396 00397 /* recursive call point */ 00398 depth_first_traversal_graphcrunch_stats(next_node, fp, traverse_mark_number); 00399 } 00400 } 00401 } 00402 }
void depth_first_traverse_stats | ( | FILE * | out, | |
short | marker_value, | |||
netlist_t * | netlist | |||
) |
Definition at line 318 of file netlist_stats.c.
00319 { 00320 int i; 00321 00322 /* start with the primary input list */ 00323 for (i = 0; i < netlist->num_top_input_nodes; i++) 00324 { 00325 if (netlist->top_input_nodes[i] != NULL) 00326 { 00327 depth_first_traversal_graphcrunch_stats(netlist->top_input_nodes[i], out, marker_value); 00328 } 00329 } 00330 /* now traverse the ground and vcc pins */ 00331 if (netlist->gnd_node != NULL) 00332 depth_first_traversal_graphcrunch_stats(netlist->gnd_node, out, marker_value); 00333 if (netlist->vcc_node != NULL) 00334 depth_first_traversal_graphcrunch_stats(netlist->vcc_node, out, marker_value); 00335 }
void display_node_stats | ( | FILE * | fp, | |
nnode_t * | node | |||
) |
Definition at line 154 of file netlist_stats.c.
00155 { 00156 fprintf(fp, "Node name: %s -->", node->name); 00157 fprintf(fp, "inputs: %d; outputs: %d; delay: %d; backward_delay: %d; sequential_level: %d; is_seq_term: %d\n", node->num_input_pins, node->num_output_pins, node->forward_level, node->backward_level, node->sequential_level, node->sequential_terminator); 00158 }
void display_per_node_stats | ( | FILE * | fp, | |
netlist_t * | netlist | |||
) |
Definition at line 91 of file netlist_stats.c.
00092 { 00093 int i; 00094 00095 /* GND nnode_t *gnd_node;*/ 00096 fprintf(fp, "GND NODE"); 00097 fprintf(fp, "gnd-----------------------------------------------------"); 00098 display_node_stats(fp, netlist->gnd_node); 00099 00100 /* VCC nnode_t *vcc_node;*/ 00101 fprintf(fp, "VCC NODE"); 00102 fprintf(fp, "vcc-----------------------------------------------------"); 00103 display_node_stats(fp, netlist->vcc_node); 00104 00105 /* PIs nnode_t** top_input_nodes; 00106 int num_top_input_nodes; */ 00107 fprintf(fp, "PI NODEs"); 00108 fprintf(fp, "pi-----------------------------------------------------"); 00109 for (i = 0; i < netlist->num_top_input_nodes; i++) 00110 { 00111 display_node_stats(fp, netlist->top_input_nodes[i]); 00112 } 00113 00114 /* POs nnode_t** top_output_nodes; 00115 int num_top_output_nodes; */ 00116 fprintf(fp, "PO NODEs"); 00117 fprintf(fp, "po-----------------------------------------------------"); 00118 for (i = 0; i < netlist->num_top_output_nodes; i++) 00119 { 00120 display_node_stats(fp, netlist->top_output_nodes[i]); 00121 } 00122 00123 /* FFs nnode_t** ff_nodes; 00124 int num_ff_nodes; */ 00125 fprintf(fp, "FF NODEs"); 00126 fprintf(fp, "ff-----------------------------------------------------"); 00127 for (i = 0; i < netlist->num_ff_nodes; i++) 00128 { 00129 display_node_stats(fp, netlist->ff_nodes[i]); 00130 } 00131 00132 /* COBINATIONAL nnode_t** internal_nodes; 00133 int num_internal_nodes; */ 00134 fprintf(fp, "COMBO NODEs"); 00135 fprintf(fp, "combo-----------------------------------------------------"); 00136 for (i = 0; i < netlist->num_internal_nodes; i++) 00137 { 00138 display_node_stats(fp, netlist->internal_nodes[i]); 00139 } 00140 00141 /* CLOCKS nnode_t** clocks; 00142 int num_clocks; */ 00143 fprintf(fp, "CLOCK NODEs"); 00144 fprintf(fp, "clock-----------------------------------------------------"); 00145 for (i = 0; i < netlist->num_clocks; i++) 00146 { 00147 display_node_stats(fp, netlist->clocks[i]); 00148 } 00149 }
void netlist_stats | ( | netlist_t * | netlist, | |
char * | path, | |||
char * | name | |||
) |
Definition at line 50 of file netlist_stats.c.
00051 { 00052 FILE *fp; 00053 char path_and_file[4096]; 00054 00055 /* open the file */ 00056 sprintf(path_and_file, "%s/%s", path, name); 00057 fp = fopen(path_and_file, "w"); 00058 00059 /* allocate the stat structure */ 00060 netlist->stats = (netlist_stats_t*)malloc(sizeof(netlist_stats_t)); 00061 netlist->stats->fanin_distribution = NULL; 00062 netlist->stats->num_fanin_distribution = 0; 00063 netlist->stats->fanout_distribution = NULL; 00064 netlist->stats->num_fanout_distribution = 0; 00065 00066 /* collect high-lelve stats */ 00067 netlist->stats->num_inputs = netlist->num_top_input_nodes; 00068 netlist->stats->num_outputs = netlist->num_top_output_nodes; 00069 netlist->stats->num_ff_nodes = netlist->num_ff_nodes; 00070 netlist->stats->num_logic_nodes = netlist->num_internal_nodes; 00071 netlist->stats->num_nodes = netlist->stats->num_inputs + netlist->stats->num_outputs + netlist->stats->num_ff_nodes + netlist->stats->num_logic_nodes; 00072 00073 /* calculate the average fanout */ 00074 calculate_avg_fanout(netlist); 00075 /* calculate the average fanin */ 00076 calculate_avg_fanin(netlist); 00077 /* calculate combinational shape of each sequential level */ 00078 calculate_combinational_shapes(netlist); 00079 00080 /* traverse the netlist looking for the stats */ 00081 depth_first_traverse_stats(fp, STATS, netlist); 00082 00083 display_per_node_stats(fp, netlist); 00084 00085 fclose(fp); 00086 }
int num_fanouts_on_output_pin | ( | nnode_t * | node, | |
int | output_pin_idx | |||
) |
Definition at line 407 of file netlist_stats.c.
00408 { 00409 nnet_t *next_net; 00410 int return_value = 0; 00411 int j; 00412 00413 if (node->output_pins[output_pin_idx]->net == NULL) 00414 return 0; 00415 00416 next_net = node->output_pins[output_pin_idx]->net; 00417 for (j = 0; j < next_net->num_fanout_pins; j++) 00418 { 00419 if (next_net->fanout_pins[j] == NULL) 00420 continue; 00421 00422 if (next_net->fanout_pins[j]->node == NULL) 00423 continue; 00424 00425 return_value++; 00426 } 00427 00428 return return_value; 00429 }