netlist_check.c File Reference

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "globals.h"
#include "errors.h"
#include "netlist_utils.h"
#include "odin_util.h"
#include "ast_util.h"
#include "string_cache.h"
#include "util.h"
#include "netlist_check.h"
#include "netlist_visualizer.h"
Include dependency graph for netlist_check.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void levelize_backwards (netlist_t *netlist)
void levelize_backwards_clean_checking_for_liveness (short ast_based, netlist_t *netlist)
void levelize_forwards (netlist_t *netlist)
void levelize_forwards_clean_checking_for_combo_loop_and_liveness (short ast_based, netlist_t *netlist)
nnode_tfind_node_at_top_of_combo_loop (nnode_t *start_node)
void depth_first_traversal_check_if_forward_leveled (short marker_value, netlist_t *netlist)
void depth_first_traverse_check_if_forward_leveled (nnode_t *node, int traverse_mark_number)
void sequential_levelized_dfs (short marker_value, netlist_t *netlist)
void depth_first_traverse_until_next_ff_or_output (nnode_t *node, nnode_t *calling_node, int traverse_mark_number, int seq_level, netlist_t *netlist)
void check_netlist (netlist_t *netlist)
void depth_traverse_check_combinational_loop (nnode_t *node, short start, STRING_CACHE *in_path)
void levelize_and_check_for_combinational_loop_and_liveness (short ast_based, netlist_t *netlist)

Function Documentation

void check_netlist ( netlist_t netlist  ) 

Definition at line 53 of file netlist_check.c.

00054 {
00055         /* create a graph output of this netlist */
00056         if (configuration.output_netlist_graphs == 1)
00057         {
00058                 /* Path is where we are */
00059                 graphVizOutputNetlist(configuration.debug_output_path, "net", 1, netlist);
00060         }
00061 }

Here is the call graph for this function:

Here is the caller graph for this function:

void depth_first_traversal_check_if_forward_leveled ( short  marker_value,
netlist_t netlist 
)

Definition at line 244 of file netlist_check.c.

00245 {
00246         int i;
00247 
00248         /* start with the primary input list */
00249         for (i = 0; i < netlist->num_top_input_nodes; i++)
00250         {
00251                 if (netlist->top_input_nodes[i] != NULL)
00252                 {
00253                         depth_first_traverse_check_if_forward_leveled(netlist->top_input_nodes[i], marker_value);
00254                 }
00255         }
00256         /* now traverse the ground and vcc pins */
00257         if (netlist->gnd_node != NULL)
00258                 depth_first_traverse_check_if_forward_leveled(netlist->gnd_node, marker_value);
00259         if (netlist->vcc_node != NULL)
00260                 depth_first_traverse_check_if_forward_leveled(netlist->vcc_node, marker_value);
00261 }

Here is the call graph for this function:

Here is the caller graph for this function:

void depth_first_traverse_check_if_forward_leveled ( nnode_t node,
int  traverse_mark_number 
)

Definition at line 266 of file netlist_check.c.

00267 {
00268         int i, j;
00269         nnode_t *next_node;
00270         nnet_t *next_net;
00271 
00272         if (node->traverse_visited == traverse_mark_number)
00273         {
00274                 return;
00275         }
00276         else
00277         {
00278                 /* ELSE - this is a new node so depth visit it */
00279 
00280                 /* mark that we have visitied this node now */
00281                 node->traverse_visited = traverse_mark_number;
00282                 
00283                 for (i = 0; i < node->num_output_pins; i++)
00284                 {
00285                         if (node->output_pins[i]->net == NULL)
00286                                 continue;
00287 
00288                         next_net = node->output_pins[i]->net;
00289                         for (j = 0; j < next_net->num_fanout_pins; j++)
00290                         {
00291                                 if (next_net->fanout_pins[j] == NULL)
00292                                         continue;
00293 
00294                                 next_node = next_net->fanout_pins[j]->node;
00295                                 if (next_node == NULL)
00296                                         continue;
00297 
00298                                 if ((next_node->forward_level == -1) && (next_node->type != FF_NODE))
00299                                 {
00300                                         graphVizOutputCombinationalNet(configuration.debug_output_path, "combo_loop", COMBO_LOOP_ERROR, /*next_node);*/ find_node_at_top_of_combo_loop(next_node));
00301                                         oassert(FALSE);
00302                                 }
00303 
00304                                 /* recursive call point */
00305                                 depth_first_traverse_check_if_forward_leveled(next_node, traverse_mark_number);
00306                         }
00307                 }
00308         }
00309 }

Here is the call graph for this function:

Here is the caller graph for this function:

void depth_first_traverse_until_next_ff_or_output ( nnode_t node,
nnode_t calling_node,
int  traverse_mark_number,
int  seq_level,
netlist_t netlist 
)

Definition at line 166 of file netlist_check.c.

00167 {
00168         int i, j;
00169         nnode_t *next_node;
00170         nnet_t *next_net;
00171 
00172         /* first, check if the clalling node should be recorderd */
00173         if ((calling_node != NULL) && ((node->type == FF_NODE) || (node->type == OUTPUT_NODE)))
00174         {
00175                 /* IF - the this node is the end of a sequential level then the node before needs to be stored */
00176                 if (calling_node->sequential_terminator == FALSE)
00177                 {
00178                         /* IF - it hasn't been stored before */
00179                         netlist->num_at_sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1] ++;
00180                         netlist->sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1] = (nnode_t**)realloc(netlist->sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1],sizeof(nnode_t*)*netlist->num_at_sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1]);
00181                         netlist->sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1][netlist->num_at_sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1]-1] = calling_node;
00182                         /* mark the node locally */
00183                         calling_node->sequential_terminator = TRUE;
00184                 }
00185         }
00186 
00187         if (node->traverse_visited == traverse_mark_number)
00188         {
00189                 /* if already visited then nothing to do */
00190                 return;
00191         }
00192         else if (node->type == CLOCK_NODE)
00193         {
00194                 /* since this is a node that touches all flip flops, don't analyze for sequential level */
00195                 return;
00196         }
00197         else if (node->type == FF_NODE)
00198         {
00199                 /* ELSE IF - this is a ff_node, so add it to the list for the next sequential level */
00200                 /* mark as traversed */
00201                 node->traverse_visited = traverse_mark_number;
00202                 node->sequential_level = seq_level+1;
00203 
00204                 /* add to the next sequntial list */
00205                 netlist->num_at_sequential_level[seq_level+1]++;
00206                 netlist->sequential_level_nodes[seq_level+1] = (nnode_t**)realloc(netlist->sequential_level_nodes[seq_level+1], sizeof(nnode_t*)*netlist->num_at_sequential_level[seq_level+1]);
00207                 netlist->sequential_level_nodes[seq_level+1][netlist->num_at_sequential_level[seq_level+1]-1] = node;
00208 
00209                 return;
00210         }
00211         else
00212         {
00213                 /* ELSE - this is a node so depth visit it */
00214 
00215                 /* mark that we have visitied this node now */
00216                 node->traverse_visited = traverse_mark_number;
00217                 node->sequential_level = seq_level;
00218                 
00219                 for (i = 0; i < node->num_output_pins; i++)
00220                 {
00221                         if (node->output_pins[i]->net == NULL)
00222                                 continue;
00223 
00224                         next_net = node->output_pins[i]->net;
00225                         for (j = 0; j < next_net->num_fanout_pins; j++)
00226                         {
00227                                 if (next_net->fanout_pins[j] == NULL)
00228                                         continue;
00229 
00230                                 next_node = next_net->fanout_pins[j]->node;
00231                                 if (next_node == NULL)
00232                                         continue;
00233 
00234                                 /* recursive call point */
00235                                 depth_first_traverse_until_next_ff_or_output(next_node, node, traverse_mark_number, seq_level, netlist);
00236                         }
00237                 }
00238         }
00239 }

Here is the caller graph for this function:

void depth_traverse_check_combinational_loop ( nnode_t node,
short  start,
STRING_CACHE in_path 
)
nnode_t * find_node_at_top_of_combo_loop ( nnode_t start_node  ) 

Definition at line 795 of file netlist_check.c.

00796 {
00797         int i;
00798         int idx_missed;
00799         nnode_t *next_node = start_node;
00800         int *fanouts_visited;
00801         short all_visited;
00802 
00803         while(TRUE)
00804         {
00805                 oassert(next_node->unique_node_data_id == LEVELIZE);
00806                 fanouts_visited = (int*)next_node->node_data;
00807                 next_node->node_data = NULL;
00808         
00809                 /* check if they've all been marked */
00810                 all_visited = TRUE;
00811                 for (i = 0; i < next_node->num_input_pins; i++)
00812                 {
00813                         if (fanouts_visited[i] == -1)
00814                         {       
00815                                 all_visited = FALSE;
00816                                 idx_missed = i;
00817                                 break;
00818                         }
00819                 }
00820         
00821                 if (all_visited == FALSE)
00822                 {
00823                         if (next_node->input_pins[idx_missed]->net->driver_pin->node->backward_level < next_node->backward_level)
00824                                 /* IF - the next node has a lower backward level than this node suggests that it is 
00825                                    closer to primary outputs and not in the combo loop */
00826                                 return next_node;
00827 
00828                         next_node = next_node->input_pins[idx_missed]->net->driver_pin->node;
00829                 }
00830                 else
00831                 {
00832                         return next_node;
00833                 }
00834         }
00835 }

Here is the caller graph for this function:

void levelize_and_check_for_combinational_loop_and_liveness ( short  ast_based,
netlist_t netlist 
)

Definition at line 67 of file netlist_check.c.

00068 {
00069         /* go from the POs backwards and mark level */
00070         levelize_backwards(netlist);
00071         /* Since the net_data (void pointer) is used to record information, we need to clean this up so that it can be used again
00072            also, during this cleaning we check if nodes are live based on all the fanout pins have been visited */
00073         levelize_backwards_clean_checking_for_liveness(ast_based, netlist);
00074 
00075         /* do a forward analysis */
00076         levelize_forwards(netlist);
00077 
00078         /* checks if there are any non-forward marked nodes */
00079         depth_first_traversal_check_if_forward_leveled(COMBO_LOOP, netlist);
00080         /* finds combo loops, but usually killed by previous.  Also cleans out net_data (void pointer) for next algorithm. */
00081         levelize_forwards_clean_checking_for_combo_loop_and_liveness(ast_based, netlist);
00082 
00083         /* assign each node which sequential level it is in, and keep the primary inputs to that level */
00084         sequential_levelized_dfs(SEQUENTIAL_LEVELIZE, netlist);
00085 }

Here is the call graph for this function:

Here is the caller graph for this function:

void levelize_backwards ( netlist_t netlist  ) 

Definition at line 579 of file netlist_check.c.

00580 {
00581         int i, j, k;
00582         int cur_back_level;
00583         short more_levels = TRUE;
00584         short all_visited = TRUE;
00585 
00586         /* add all the POs and FFs POs as backward level 0 */
00587         cur_back_level = 0;
00588         netlist->num_backward_levels = 1;
00589         netlist->num_at_backward_level = (int*)realloc(netlist->num_at_backward_level, sizeof(int)*netlist->num_backward_levels);
00590         netlist->backward_levels = (nnode_t***)realloc(netlist->backward_levels, sizeof(nnode_t**)*(netlist->num_backward_levels));
00591         netlist->backward_levels[netlist->num_backward_levels-1] = NULL;
00592         netlist->num_at_backward_level[netlist->num_backward_levels-1] = 0;
00593         for (i = 0; i < netlist->num_top_output_nodes; i++)
00594         {
00595                 if (netlist->top_output_nodes[i] != NULL)
00596                 {
00597                         netlist->backward_levels[cur_back_level] = (nnode_t**)realloc(netlist->backward_levels[cur_back_level], sizeof(nnode_t*)*(netlist->num_at_backward_level[cur_back_level]+1));
00598                         netlist->backward_levels[cur_back_level][netlist->num_at_backward_level[cur_back_level]] = netlist->top_output_nodes[i];
00599                         netlist->num_at_backward_level[cur_back_level]++;
00600                         netlist->top_output_nodes[i]->backward_level = 0;
00601                 }
00602         }
00603         for (i = 0; i < netlist->num_ff_nodes; i++)
00604         {
00605                 if (netlist->ff_nodes[i] != NULL)
00606                 {
00607                         netlist->backward_levels[cur_back_level] = (nnode_t**)realloc(netlist->backward_levels[cur_back_level], sizeof(nnode_t*)*(netlist->num_at_backward_level[cur_back_level]+1));
00608                         netlist->backward_levels[cur_back_level][netlist->num_at_backward_level[cur_back_level]] = netlist->ff_nodes[i];
00609                         netlist->num_at_backward_level[cur_back_level]++;
00610                         netlist->ff_nodes[i]->backward_level = 0;
00611                 }
00612         }
00613 
00614         while(more_levels)
00615         {
00616                 /* another level so add space */
00617                 netlist->num_backward_levels ++;
00618                 netlist->num_at_backward_level = (int*)realloc(netlist->num_at_backward_level, sizeof(int)*netlist->num_backward_levels);
00619                 netlist->backward_levels = (nnode_t***)realloc(netlist->backward_levels, sizeof(nnode_t**)*(netlist->num_backward_levels));
00620                 netlist->backward_levels[netlist->num_backward_levels-1] = NULL;
00621                 netlist->num_at_backward_level[netlist->num_backward_levels-1] = 0;
00622 
00623                 /* go through each element at this level */
00624                 for (i = 0; i < netlist->num_at_backward_level[cur_back_level]; i++)
00625                 {
00626                         nnode_t *current_node = netlist->backward_levels[cur_back_level][i];
00627                         if (current_node == NULL)
00628                                 continue;
00629 
00630                         /* at each node visit all the inputs */
00631                         for (j = 0; j < current_node->num_input_pins; j++)
00632                         {
00633                                 int *fanouts_visited;
00634                                 if (current_node->input_pins[j] == NULL)
00635                                         continue; 
00636 
00637                                 /* visit the fanout point */
00638                                 nnet_t *fanout_net = current_node->input_pins[j]->net;
00639 
00640                                 if (fanout_net->net_data == NULL)
00641                                 {
00642                                         int idx;
00643                                         /* if this fanout hasn't been visited yet this will be null */
00644                                         fanouts_visited = (int*)malloc(sizeof(int)*(fanout_net->num_fanout_pins));
00645                                         
00646                                         for (idx = 0; idx < fanout_net->num_fanout_pins; idx++)
00647                                         {
00648                                                 fanouts_visited[idx] = -1;
00649                                         }
00650                                         
00651                                         fanout_net->net_data = (void*)fanouts_visited;
00652                                         fanout_net->unique_net_data_id = LEVELIZE;
00653                                 }
00654                                 else 
00655                                 {
00656                                         /* ELSE - get the list */
00657                                         fanouts_visited = (int*)fanout_net->net_data;
00658                                         oassert(fanout_net->unique_net_data_id == LEVELIZE);
00659                                 }
00660 
00661                                 /* mark this entry as visited */
00662                                 if(fanout_net->driver_pin != NULL)
00663                                 {
00664                                         fanouts_visited[current_node->input_pins[j]->pin_net_idx] = cur_back_level;
00665                                 }
00666 
00667                                 /* check if they've all been marked */
00668                                 all_visited = TRUE;
00669                                 for (k = 0; k < fanout_net->num_fanout_pins; k++)
00670                                 {
00671                                         if ((fanout_net->fanout_pins[k] != NULL) && (fanout_net->fanout_pins[k]->node != NULL) && (fanouts_visited[k] == -1))
00672                                         {       
00673                                                 all_visited = FALSE;
00674                                                 break;
00675                                         }
00676                                 }
00677 
00678                                 if ((all_visited == TRUE) && (fanout_net->driver_pin->node->type != FF_NODE))
00679                                 {
00680                                         /* This one has been visited by everyone */
00681                                         if (fanout_net->driver_pin->node->backward_level == -1)
00682                                         {
00683                                                 /* already added to a list...this means that we won't have the correct ordering */
00684                                                 netlist->backward_levels[cur_back_level+1] = (nnode_t**)realloc(netlist->backward_levels[cur_back_level+1], sizeof(nnode_t*)*(netlist->num_at_backward_level[cur_back_level+1]+1));
00685                                                 netlist->backward_levels[cur_back_level+1][netlist->num_at_backward_level[cur_back_level+1]] = fanout_net->driver_pin->node;
00686                                                 netlist->num_at_backward_level[cur_back_level+1]++;
00687                                         }
00688 
00689                                         fanout_net->driver_pin->node->backward_level = cur_back_level+1;
00690                                 }
00691                         }
00692                 }
00693 
00694                 /* check if tere are more elements to procees at the next level */
00695                 if (netlist->num_at_backward_level[cur_back_level+1] > 0)
00696                 {
00697                         /* there are elements in the next set then process */
00698                         cur_back_level++;
00699                 }
00700                 else
00701                 {
00702                         /* ELSE - we've levelized backwards */
00703                         more_levels = FALSE;
00704                 }
00705         }
00706 }

Here is the caller graph for this function:

void levelize_backwards_clean_checking_for_liveness ( short  ast_based,
netlist_t netlist 
)

Definition at line 711 of file netlist_check.c.

00712 {
00713         int i, j, k;
00714         int cur_back_level;
00715         short more_levels = TRUE;
00716         short all_visited = TRUE;
00717 
00718         cur_back_level = 0;
00719 
00720         while(more_levels)
00721         {
00722                 /* go through each element at this level */
00723                 for (i = 0; i < netlist->num_at_backward_level[cur_back_level]; i++)
00724                 {
00725                         nnode_t *current_node = netlist->backward_levels[cur_back_level][i];
00726                         if (current_node == NULL)
00727                                 continue;
00728 
00729                         /* at each node visit all the inputs */
00730                         for (j = 0; j < current_node->num_input_pins; j++)
00731                         {
00732                                 int *fanouts_visited;
00733                                 if (current_node->input_pins[j] == NULL)
00734                                         continue; 
00735 
00736                                 /* visit the fanout point */
00737                                 nnet_t *fanout_net = current_node->input_pins[j]->net;
00738 
00739                                 if (fanout_net->net_data == NULL)
00740                                 {
00741                                         /* IF - already cleaned */
00742                                         oassert(fanout_net->unique_net_data_id == -1);
00743                                 }
00744                                 else 
00745                                 {
00746                                         /* ELSE - get the list */
00747                                         oassert(fanout_net->unique_net_data_id == LEVELIZE);
00748                                         fanouts_visited = (int*)fanout_net->net_data;
00749                                         fanout_net->net_data = NULL;
00750 
00751                                         /* check if they've all been marked */
00752                                         all_visited = TRUE;
00753                                         for (k = 0; k < fanout_net->num_fanout_pins; k++)
00754                                         {
00755                                                 if ((fanout_net->fanout_pins[k] != NULL) && (fanout_net->fanout_pins[k]->node != NULL) && (fanouts_visited[k] == -1))
00756                                                 {       
00757                                                         all_visited = FALSE;
00758                                                         break;
00759                                                 }
00760                                         }
00761 
00762                                         if (all_visited == FALSE)
00763                                         {
00764                                                 /* one of these nodes was not visited on the backward analysis */
00765                                                 if (ast_based)
00766                                                         warning_message(NETLIST_ERROR, current_node->related_ast_node->line_number, current_node->related_ast_node->file_number, "Liveness check on backward pass.  Node %s is missing a driving pin idx %d\n", current_node->name, k);
00767                                                 else
00768                                                         warning_message(NETLIST_ERROR, -1, -1, "Liveness check on backward pass.  Node %s is missing a driving pin idx %d\n", current_node->name, k);
00769                                         }
00770 
00771                                         /* free the data and reset to be used elsewhere */
00772                                         free(fanouts_visited);
00773                                         fanout_net->unique_net_data_id = -1;
00774                                 }
00775                         }
00776                 }
00777 
00778                 /* check if tere are more elements to procees at the next level */
00779                 if (netlist->num_at_backward_level[cur_back_level+1] > 0)
00780                 {
00781                         /* there are elements in the next set then process */
00782                         cur_back_level++;
00783                 }
00784                 else
00785                 {
00786                         /* ELSE - we've levelized backwards */
00787                         more_levels = FALSE;
00788                 }
00789         }
00790 }

Here is the call graph for this function:

Here is the caller graph for this function:

void levelize_forwards ( netlist_t netlist  ) 

Definition at line 315 of file netlist_check.c.

00316 {
00317         int i, j, k;
00318         int cur_for_level;
00319         short more_levels = TRUE;
00320         short all_visited = TRUE;
00321 
00322         /* add all the POs and FFs POs as forward level 0 */
00323         cur_for_level = 0;
00324         netlist->num_forward_levels = 1;
00325         netlist->num_at_forward_level = (int*)realloc(netlist->num_at_forward_level, sizeof(int)*netlist->num_forward_levels);
00326         netlist->forward_levels = (nnode_t***)realloc(netlist->forward_levels, sizeof(nnode_t**)*(netlist->num_forward_levels));
00327         netlist->forward_levels[netlist->num_forward_levels-1] = NULL;
00328         netlist->num_at_forward_level[netlist->num_forward_levels-1] = 0;
00329         for (i = 0; i < netlist->num_top_input_nodes+3; i++)
00330         {
00331                 if ((i == netlist->num_top_input_nodes) && (netlist->vcc_node != NULL))
00332                 {
00333                         /* vcc */
00334                         netlist->forward_levels[cur_for_level] = (nnode_t**)realloc(netlist->forward_levels[cur_for_level], sizeof(nnode_t*)*(netlist->num_at_forward_level[cur_for_level]+1));
00335                         netlist->forward_levels[cur_for_level][netlist->num_at_forward_level[cur_for_level]] = netlist->vcc_node;
00336                         netlist->num_at_forward_level[cur_for_level]++;
00337                         netlist->vcc_node->forward_level = 0;
00338                 }
00339                 else if ((i == netlist->num_top_input_nodes+1) && (netlist->gnd_node != NULL))
00340                 {
00341                         /* gnd */
00342                         netlist->forward_levels[cur_for_level] = (nnode_t**)realloc(netlist->forward_levels[cur_for_level], sizeof(nnode_t*)*(netlist->num_at_forward_level[cur_for_level]+1));
00343                         netlist->forward_levels[cur_for_level][netlist->num_at_forward_level[cur_for_level]] = netlist->gnd_node;
00344                         netlist->num_at_forward_level[cur_for_level]++;
00345                         netlist->gnd_node->forward_level = 0;
00346                 }
00347                 else if ((i == netlist->num_top_input_nodes+2) && (netlist->pad_node != NULL))
00348                 {
00349                         /* pad */
00350                         netlist->forward_levels[cur_for_level] = (nnode_t**)realloc(netlist->forward_levels[cur_for_level], sizeof(nnode_t*)*(netlist->num_at_forward_level[cur_for_level]+1));
00351                         netlist->forward_levels[cur_for_level][netlist->num_at_forward_level[cur_for_level]] = netlist->pad_node;
00352                         netlist->num_at_forward_level[cur_for_level]++;
00353                         netlist->pad_node->forward_level = 0;
00354                 }
00355                 else if (i >= netlist->num_top_input_nodes)
00356                 {
00357                         continue;
00358                 }
00359                 else if (netlist->top_input_nodes[i] != NULL)
00360                 {
00361                         netlist->forward_levels[cur_for_level] = (nnode_t**)realloc(netlist->forward_levels[cur_for_level], sizeof(nnode_t*)*(netlist->num_at_forward_level[cur_for_level]+1));
00362                         netlist->forward_levels[cur_for_level][netlist->num_at_forward_level[cur_for_level]] = netlist->top_input_nodes[i];
00363                         netlist->num_at_forward_level[cur_for_level]++;
00364                         netlist->top_input_nodes[i]->forward_level = 0;
00365                 }
00366         }
00367         for (i = 0; i < netlist->num_ff_nodes; i++)
00368         {
00369                 if (netlist->ff_nodes[i] != NULL)
00370                 {
00371                         netlist->forward_levels[cur_for_level] = (nnode_t**)realloc(netlist->forward_levels[cur_for_level], sizeof(nnode_t*)*(netlist->num_at_forward_level[cur_for_level]+1));
00372                         netlist->forward_levels[cur_for_level][netlist->num_at_forward_level[cur_for_level]] = netlist->ff_nodes[i];
00373                         netlist->num_at_forward_level[cur_for_level]++;
00374                         netlist->ff_nodes[i]->forward_level = 0;
00375                 }
00376         }
00377 
00378         while(more_levels)
00379         {
00380                 /* another level so add space */
00381                 netlist->num_forward_levels ++;
00382                 netlist->num_at_forward_level = (int*)realloc(netlist->num_at_forward_level, sizeof(int)*netlist->num_forward_levels);
00383                 netlist->forward_levels = (nnode_t***)realloc(netlist->forward_levels, sizeof(nnode_t**)*(netlist->num_forward_levels));
00384                 netlist->forward_levels[netlist->num_forward_levels-1] = NULL;
00385                 netlist->num_at_forward_level[netlist->num_forward_levels-1] = 0;
00386 
00387                 /* go through each element at this level */
00388                 for (i = 0; i < netlist->num_at_forward_level[cur_for_level]; i++)
00389                 {
00390                         nnode_t *current_node = netlist->forward_levels[cur_for_level][i];
00391                         if (current_node == NULL)
00392                                 continue;
00393 
00394                         /* at each node visit all the inputs */
00395                         for (j = 0; j < current_node->num_output_pins; j++)
00396                         {
00397                                 int *fanouts_visited;
00398                                 if (current_node->output_pins[j] == NULL)
00399                                         continue; 
00400 
00401                                 for (k = 0; k < current_node->output_pins[j]->net->num_fanout_pins; k++)
00402                                 {
00403                                         int idx;
00404                                         /* visit the fanout point */
00405                                         if ((current_node->output_pins[j] == NULL) || (current_node->output_pins[j]->net == NULL) || ( current_node->output_pins[j]->net->fanout_pins[k] == NULL))
00406                                                 continue;
00407 
00408                                         nnode_t *output_node = current_node->output_pins[j]->net->fanout_pins[k]->node;
00409 
00410                                         if (output_node == NULL)
00411                                                 continue;
00412         
00413                                         if (output_node->node_data == NULL)
00414                                         {
00415                                                 /* if this fanout hasn't been visited yet this will be null */
00416                                                 fanouts_visited = (int*)malloc(sizeof(int)*(output_node->num_input_pins));
00417                                                 
00418                                                 for (idx = 0; idx < output_node->num_input_pins; idx++)
00419                                                 {
00420                                                         fanouts_visited[idx] = -1;
00421                                                 }
00422                                                 
00423                                                 output_node->node_data = (void*)fanouts_visited;
00424                                                 output_node->unique_node_data_id = LEVELIZE;
00425                                         }
00426                                         else 
00427                                         {
00428                                                 /* ELSE - get the list */
00429                                                 oassert(output_node->unique_node_data_id == LEVELIZE);
00430                                                 fanouts_visited = (int*)output_node->node_data;
00431                                         }
00432         
00433                                         /* mark this entry as visited */
00434                                         fanouts_visited[current_node->output_pins[j]->net->fanout_pins[k]->pin_node_idx] = cur_for_level;
00435         
00436                                         /* check if they've all been marked */
00437                                         all_visited = TRUE;
00438                                         for (idx = 0; idx < output_node->num_input_pins; idx++)
00439                                         {
00440                                                 if (fanouts_visited[idx] == -1)
00441                                                 {       
00442                                                         all_visited = FALSE;
00443                                                         break;
00444                                                 }
00445                                         }
00446         
00447                                         if ((all_visited == TRUE) && (output_node->type != FF_NODE))
00448                                         {
00449                                                 /* This one has been visited by everyone */
00450                                                 netlist->forward_levels[cur_for_level+1] = (nnode_t**)realloc(netlist->forward_levels[cur_for_level+1], sizeof(nnode_t*)*(netlist->num_at_forward_level[cur_for_level+1]+1));
00451                                                 netlist->forward_levels[cur_for_level+1][netlist->num_at_forward_level[cur_for_level+1]] = output_node;
00452                                                 netlist->num_at_forward_level[cur_for_level+1]++;
00453         
00454                                                 output_node->forward_level = cur_for_level+1;
00455                                         }
00456                                 }
00457                         }
00458                 }
00459 
00460                 /* check if tere are more elements to procees at the next level */
00461                 if (netlist->num_at_forward_level[cur_for_level+1] > 0)
00462                 {
00463                         /* there are elements in the next set then process */
00464                         cur_for_level++;
00465                 }
00466                 else
00467                 {
00468                         /* ELSE - we've levelized forwards */
00469                         more_levels = FALSE;
00470                 }
00471         }
00472 }

Here is the call graph for this function:

Here is the caller graph for this function:

void levelize_forwards_clean_checking_for_combo_loop_and_liveness ( short  ast_based,
netlist_t netlist 
)

Definition at line 476 of file netlist_check.c.

00477 {
00478         int i, j, k;
00479         int cur_for_level;
00480         short more_levels = TRUE;
00481         short all_visited = TRUE;
00482 
00483         cur_for_level = 0;
00484 
00485         while(more_levels)
00486         {
00487                 /* go through each element at this level */
00488                 for (i = 0; i < netlist->num_at_forward_level[cur_for_level]; i++)
00489                 {
00490                         nnode_t *current_node = netlist->forward_levels[cur_for_level][i];
00491                         if (current_node == NULL)
00492                                 continue;
00493 
00494                         /* at each node visit all the inputs */
00495                         for (j = 0; j < current_node->num_output_pins; j++)
00496                         {
00497                                 int *fanouts_visited;
00498                                 if (current_node->output_pins[j] == NULL)
00499                                         continue; 
00500 
00501                                 for (k = 0; k < current_node->output_pins[j]->net->num_fanout_pins; k++)
00502                                 {
00503                                         if ((current_node->output_pins[j] == NULL) || (current_node->output_pins[j]->net == NULL) || ( current_node->output_pins[j]->net->fanout_pins[k] == NULL))
00504                                                 continue;
00505 
00506                                         /* visit the fanout point */
00507                                         nnode_t *output_node = current_node->output_pins[j]->net->fanout_pins[k]->node;
00508 
00509                                         if (output_node == NULL)
00510                                                 continue;
00511         
00512                                         if (output_node->node_data == NULL)
00513                                         {
00514                                                 oassert(output_node->unique_node_data_id == RESET);
00515                                         }
00516                                         else 
00517                                         {
00518                                                 int idx;
00519                                                 int idx_missed;
00520                                                 /* ELSE - get the list */
00521                                                 oassert(output_node->unique_node_data_id == LEVELIZE);
00522                                                 fanouts_visited = (int*)output_node->node_data;
00523                                                 output_node->node_data = NULL;
00524 
00525                                                 /* check if they've all been marked */
00526                                                 all_visited = TRUE;
00527                                                 for (idx = 0; idx < output_node->num_input_pins; idx++)
00528                                                 {
00529                                                         if (fanouts_visited[idx] == -1)
00530                                                         {       
00531                                                                 all_visited = FALSE;
00532                                                                 idx_missed = idx;
00533                                                                 break;
00534                                                         }
00535                                                 }
00536         
00537                                                 if (all_visited == FALSE)
00538                                                 {
00539                                                         /* Combo node since one of the outputs hasn'y been visisted. */
00540                                                         if (ast_based)
00541                                                                 error_message(NETLIST_ERROR, output_node->related_ast_node->line_number, output_node->related_ast_node->file_number, "!!!Combinational loop on forward pass.  Node %s is missing a driven pin idx %d.  Isn't neccessarily the culprit of the combinational loop.  Odin only detects combinational loops, but currently doesn't pinpoint.\n", output_node->name, idx);
00542                                                         else
00543                                                                 error_message(NETLIST_ERROR, -1, -1, "!!!Combinational loop on forward pass.  Node %s is missing a driven pin idx %d.  Isn't neccessarily the culprit of the combinational loop.  Odin only detects combinational loops, but currently doesn't pinpoint.\n", output_node->name, idx);
00544                                                 }
00545                                                 /* free the data and reset to be used elsewhere */
00546                                                 free(fanouts_visited);
00547                                                 output_node->unique_node_data_id = RESET;
00548                                         }
00549 
00550                                         if ((output_node->backward_level == -1) && (output_node->type != FF_NODE))
00551                                         {
00552                                                 if (ast_based)
00553                                                         warning_message(NETLIST_ERROR, output_node->related_ast_node->line_number, output_node->related_ast_node->file_number, "Node does not connect to a primary output or FF...DEAD NODE!!!.  Node %s is not connected to a primary output.\n", output_node->name);
00554                                                 else
00555                                                         warning_message(NETLIST_ERROR, -1, -1, "Node does not connect to a primary output or FF...DEAD NODE!!!.  Node %s is not connected to a primary output.\n", output_node->name);
00556                                         }
00557                                 }
00558                         }
00559                 }
00560 
00561                 /* check if tere are more elements to procees at the next level */
00562                 if (netlist->num_at_forward_level[cur_for_level+1] > 0)
00563                 {
00564                         /* there are elements in the next set then process */
00565                         cur_for_level++;
00566                 }
00567                 else
00568                 {
00569                         /* ELSE - we've levelized forwards */
00570                         more_levels = FALSE;
00571                 }
00572         }
00573 }

Here is the call graph for this function:

Here is the caller graph for this function:

void sequential_levelized_dfs ( short  marker_value,
netlist_t netlist 
)

Definition at line 90 of file netlist_check.c.

00091 {
00092         int i;
00093 
00094         int sequential_level = 0;
00095         netlist->num_sequential_levels = 1;
00096         netlist->num_at_sequential_level = (int*)realloc(netlist->num_at_sequential_level, sizeof(int)*netlist->num_sequential_levels);
00097         netlist->sequential_level_nodes = (nnode_t***)realloc(netlist->sequential_level_nodes, sizeof(nnode_t**)*(netlist->num_sequential_levels));
00098         netlist->sequential_level_nodes[netlist->num_sequential_levels-1] = NULL;
00099         netlist->num_at_sequential_level[netlist->num_sequential_levels-1] = 0;
00100 
00101         /* allocate the first list.  Includes vcc and gnd */
00102         netlist->sequential_level_nodes[sequential_level] = (nnode_t**)realloc(netlist->sequential_level_nodes[sequential_level], sizeof(nnode_t*)*(netlist->num_top_input_nodes+2));
00103         
00104         /* add all the primary nodes to the first level */
00105         for (i = 0; i < netlist->num_top_input_nodes; i++)
00106         {
00107                 if (netlist->top_input_nodes[i] != NULL)
00108                 {
00109                         netlist->sequential_level_nodes[sequential_level][i] = netlist->top_input_nodes[i];
00110                         netlist->num_at_sequential_level[sequential_level]++;
00111                         /* record the level */
00112                         netlist->top_input_nodes[i]->sequential_level = sequential_level;
00113                 }
00114         }
00115 
00116         /* now traverse the ground and vcc pins */
00117         if (netlist->gnd_node != NULL)
00118         {
00119                 netlist->sequential_level_nodes[sequential_level][i] = netlist->gnd_node;
00120                 netlist->num_at_sequential_level[sequential_level]++;
00121                 /* record the level */
00122                 netlist->gnd_node->sequential_level = sequential_level;
00123         }
00124         if (netlist->vcc_node != NULL)
00125         {
00126                 netlist->sequential_level_nodes[sequential_level][i+1] = netlist->vcc_node;
00127                 netlist->num_at_sequential_level[sequential_level]++;
00128                 /* record the level */
00129                 netlist->vcc_node->sequential_level = sequential_level;
00130         }
00131 
00132         while (netlist->num_at_sequential_level[sequential_level] > 0)
00133         {
00134                 /* WHILE there are PIs at this level */
00135 
00136                 /* Allocate the next level of storage since this part is a forward thing of the next flip-flops at the level */
00137                 /* add anothersequential level.  Note, needs to be done before we depth first the current combinational level. */               
00138                 netlist->num_sequential_levels ++;
00139                 netlist->sequential_level_nodes = (nnode_t***)realloc(netlist->sequential_level_nodes, sizeof(nnode_t**)*(netlist->num_sequential_levels));
00140                 netlist->num_at_sequential_level = (int*)realloc(netlist->num_at_sequential_level, sizeof(int)*netlist->num_sequential_levels);
00141                 netlist->sequential_level_nodes[netlist->num_sequential_levels-1] = NULL;
00142                 netlist->num_at_sequential_level[netlist->num_sequential_levels-1] = 0;
00143 
00144                 /* deals with recording the combinational nodes that terminate this level */
00145                 netlist->num_sequential_level_combinational_termination_nodes ++;
00146                 netlist->sequential_level_combinational_termination_node = (nnode_t***)realloc(netlist->sequential_level_combinational_termination_node, sizeof(nnode_t**)*(netlist->num_sequential_level_combinational_termination_nodes));
00147                 netlist->num_at_sequential_level_combinational_termination_node = (int*)realloc(netlist->num_at_sequential_level_combinational_termination_node, sizeof(int)*netlist->num_sequential_level_combinational_termination_nodes);
00148                 netlist->sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1] = NULL;
00149                 netlist->num_at_sequential_level_combinational_termination_node[netlist->num_sequential_level_combinational_termination_nodes-1] = 0;
00150 
00151                 /* go through the entire list, mark with sequential level, and build the next list */
00152                 for (i = 0; i < netlist->num_at_sequential_level[sequential_level]; i++)
00153                 {
00154                         depth_first_traverse_until_next_ff_or_output(netlist->sequential_level_nodes[sequential_level][i], NULL, marker_value, sequential_level, netlist);
00155                 }
00156 
00157                 /* now potentially do next sequential level */
00158                 sequential_level ++;
00159         }
00160 
00161 }

Here is the call graph for this function:

Here is the caller graph for this function:

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