netlist_stats.c File Reference

#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"
Include dependency graph for netlist_stats.c:
This graph shows which files directly or indirectly include this file:

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)

Function Documentation

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the caller graph for this function:

Generated on Tue Aug 2 10:43:21 2011 for ODIN_II by  doxygen 1.6.3