#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"
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_t * | find_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) |
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 }
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 }
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 }
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 }
void depth_traverse_check_combinational_loop | ( | nnode_t * | node, | |
short | start, | |||
STRING_CACHE * | in_path | |||
) |
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 }
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 }
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 }
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 }
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 }
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 }
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 }