00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <string.h>
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include "types.h"
00028 #include "globals.h"
00029 #include "errors.h"
00030 #include "netlist_utils.h"
00031 #include "odin_util.h"
00032 #include "ast_util.h"
00033 #include "string_cache.h"
00034 #include "util.h"
00035 #include "netlist_check.h"
00036 #include "netlist_visualizer.h"
00037
00038 void levelize_backwards(netlist_t *netlist);
00039 void levelize_backwards_clean_checking_for_liveness(short ast_based, netlist_t *netlist);
00040 void levelize_forwards(netlist_t *netlist);
00041 void levelize_forwards_clean_checking_for_combo_loop_and_liveness(short ast_based, netlist_t *netlist);
00042 nnode_t *find_node_at_top_of_combo_loop(nnode_t *start_node);
00043 void depth_first_traversal_check_if_forward_leveled(short marker_value, netlist_t *netlist);
00044 void depth_first_traverse_check_if_forward_leveled(nnode_t *node, int traverse_mark_number);
00045
00046 void sequential_levelized_dfs(short marker_value, netlist_t *netlist);
00047 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);
00048
00049
00050
00051
00052
00053 void check_netlist(netlist_t *netlist)
00054 {
00055
00056 if (configuration.output_netlist_graphs == 1)
00057 {
00058
00059 graphVizOutputNetlist(configuration.debug_output_path, "net", 1, netlist);
00060 }
00061 }
00062
00063 void depth_traverse_check_combinational_loop(nnode_t *node, short start, STRING_CACHE *in_path);
00064
00065
00066
00067 void levelize_and_check_for_combinational_loop_and_liveness(short ast_based, netlist_t *netlist)
00068 {
00069
00070 levelize_backwards(netlist);
00071
00072
00073 levelize_backwards_clean_checking_for_liveness(ast_based, netlist);
00074
00075
00076 levelize_forwards(netlist);
00077
00078
00079 depth_first_traversal_check_if_forward_leveled(COMBO_LOOP, netlist);
00080
00081 levelize_forwards_clean_checking_for_combo_loop_and_liveness(ast_based, netlist);
00082
00083
00084 sequential_levelized_dfs(SEQUENTIAL_LEVELIZE, netlist);
00085 }
00086
00087
00088
00089
00090 void sequential_levelized_dfs(short marker_value, netlist_t *netlist)
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
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
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
00112 netlist->top_input_nodes[i]->sequential_level = sequential_level;
00113 }
00114 }
00115
00116
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
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
00129 netlist->vcc_node->sequential_level = sequential_level;
00130 }
00131
00132 while (netlist->num_at_sequential_level[sequential_level] > 0)
00133 {
00134
00135
00136
00137
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
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
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
00158 sequential_level ++;
00159 }
00160
00161 }
00162
00163
00164
00165
00166 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)
00167 {
00168 int i, j;
00169 nnode_t *next_node;
00170 nnet_t *next_net;
00171
00172
00173 if ((calling_node != NULL) && ((node->type == FF_NODE) || (node->type == OUTPUT_NODE)))
00174 {
00175
00176 if (calling_node->sequential_terminator == FALSE)
00177 {
00178
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
00183 calling_node->sequential_terminator = TRUE;
00184 }
00185 }
00186
00187 if (node->traverse_visited == traverse_mark_number)
00188 {
00189
00190 return;
00191 }
00192 else if (node->type == CLOCK_NODE)
00193 {
00194
00195 return;
00196 }
00197 else if (node->type == FF_NODE)
00198 {
00199
00200
00201 node->traverse_visited = traverse_mark_number;
00202 node->sequential_level = seq_level+1;
00203
00204
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
00214
00215
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
00235 depth_first_traverse_until_next_ff_or_output(next_node, node, traverse_mark_number, seq_level, netlist);
00236 }
00237 }
00238 }
00239 }
00240
00241
00242
00243
00244 void depth_first_traversal_check_if_forward_leveled(short marker_value, netlist_t *netlist)
00245 {
00246 int i;
00247
00248
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
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 }
00262
00263
00264
00265
00266 void depth_first_traverse_check_if_forward_leveled(nnode_t *node, int traverse_mark_number)
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
00279
00280
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, find_node_at_top_of_combo_loop(next_node));
00301 oassert(FALSE);
00302 }
00303
00304
00305 depth_first_traverse_check_if_forward_leveled(next_node, traverse_mark_number);
00306 }
00307 }
00308 }
00309 }
00310
00311
00312
00313
00314
00315 void levelize_forwards(netlist_t *netlist)
00316 {
00317 int i, j, k;
00318 int cur_for_level;
00319 short more_levels = TRUE;
00320 short all_visited = TRUE;
00321
00322
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
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
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
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
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
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
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
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
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
00429 oassert(output_node->unique_node_data_id == LEVELIZE);
00430 fanouts_visited = (int*)output_node->node_data;
00431 }
00432
00433
00434 fanouts_visited[current_node->output_pins[j]->net->fanout_pins[k]->pin_node_idx] = cur_for_level;
00435
00436
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
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
00461 if (netlist->num_at_forward_level[cur_for_level+1] > 0)
00462 {
00463
00464 cur_for_level++;
00465 }
00466 else
00467 {
00468
00469 more_levels = FALSE;
00470 }
00471 }
00472 }
00473
00474
00475
00476 void levelize_forwards_clean_checking_for_combo_loop_and_liveness(short ast_based, netlist_t *netlist)
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
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
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
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
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
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
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
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
00562 if (netlist->num_at_forward_level[cur_for_level+1] > 0)
00563 {
00564
00565 cur_for_level++;
00566 }
00567 else
00568 {
00569
00570 more_levels = FALSE;
00571 }
00572 }
00573 }
00574
00575
00576
00577
00578
00579 void levelize_backwards(netlist_t *netlist)
00580 {
00581 int i, j, k;
00582 int cur_back_level;
00583 short more_levels = TRUE;
00584 short all_visited = TRUE;
00585
00586
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
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
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
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
00638 nnet_t *fanout_net = current_node->input_pins[j]->net;
00639
00640 if (fanout_net->net_data == NULL)
00641 {
00642 int idx;
00643
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
00657 fanouts_visited = (int*)fanout_net->net_data;
00658 oassert(fanout_net->unique_net_data_id == LEVELIZE);
00659 }
00660
00661
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
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
00681 if (fanout_net->driver_pin->node->backward_level == -1)
00682 {
00683
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
00695 if (netlist->num_at_backward_level[cur_back_level+1] > 0)
00696 {
00697
00698 cur_back_level++;
00699 }
00700 else
00701 {
00702
00703 more_levels = FALSE;
00704 }
00705 }
00706 }
00707
00708
00709
00710
00711 void levelize_backwards_clean_checking_for_liveness(short ast_based, netlist_t *netlist)
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
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
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
00737 nnet_t *fanout_net = current_node->input_pins[j]->net;
00738
00739 if (fanout_net->net_data == NULL)
00740 {
00741
00742 oassert(fanout_net->unique_net_data_id == -1);
00743 }
00744 else
00745 {
00746
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
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
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
00772 free(fanouts_visited);
00773 fanout_net->unique_net_data_id = -1;
00774 }
00775 }
00776 }
00777
00778
00779 if (netlist->num_at_backward_level[cur_back_level+1] > 0)
00780 {
00781
00782 cur_back_level++;
00783 }
00784 else
00785 {
00786
00787 more_levels = FALSE;
00788 }
00789 }
00790 }
00791
00792
00793
00794
00795 nnode_t *find_node_at_top_of_combo_loop(nnode_t *start_node)
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
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
00825
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 }