VIS
|
00001 00019 #include "resInt.h" 00020 00021 static char rcsid[] UNUSED = "$Id: resLayer.c,v 1.36 2005/04/16 07:31:03 fabio Exp $"; 00022 00023 /*---------------------------------------------------------------------------*/ 00024 /* Constant declarations */ 00025 /*---------------------------------------------------------------------------*/ 00026 00027 /*---------------------------------------------------------------------------*/ 00028 /* Structure declarations */ 00029 /*---------------------------------------------------------------------------*/ 00030 00031 /*---------------------------------------------------------------------------*/ 00032 /* Type declarations */ 00033 /*---------------------------------------------------------------------------*/ 00034 00035 /*---------------------------------------------------------------------------*/ 00036 /* Variable declarations */ 00037 /*---------------------------------------------------------------------------*/ 00038 00039 /*---------------------------------------------------------------------------*/ 00040 /* Macro declarations */ 00041 /*---------------------------------------------------------------------------*/ 00042 00045 /*---------------------------------------------------------------------------*/ 00046 /* Static function prototypes */ 00047 /*---------------------------------------------------------------------------*/ 00048 00049 static array_t * ComputeCompositionLayersAsap(Ntk_Network_t *network, array_t *outputArray, array_t *ignoreArray); 00050 static array_t * ComputeCompositionLayersAlap(Ntk_Network_t *network, array_t *outputArray, array_t *ignoreArray); 00051 static int ComputeAlapLabelling(Ntk_Network_t *network, st_table *nodeLabelling); 00052 static void ComputeAlapLabellingRecur(Ntk_Node_t *node, st_table *nodeLabelling); 00053 static st_table * ComputeTransitiveFanin(array_t *outputArray); 00054 static void ComputeTransitiveFaninRecur(Ntk_Node_t *nodePtr, st_table *faninTable); 00055 static void RecursiveDecrementFanoutCount(Ntk_Node_t *nodePtr, st_table *fanoutCountTable, st_table *visitedTable); 00056 00060 /*---------------------------------------------------------------------------*/ 00061 /* Definition of exported functions */ 00062 /*---------------------------------------------------------------------------*/ 00063 00064 00065 /*---------------------------------------------------------------------------*/ 00066 /* Definition of internal functions */ 00067 /*---------------------------------------------------------------------------*/ 00068 00091 array_t * 00092 ResComputeCompositionLayers(Ntk_Network_t *network, 00093 array_t *outputArray, 00094 array_t *ignoreArray) 00095 { 00096 ResLayerScheduleMethod layerMethod; /* read from the set value */ 00097 array_t *result; /* Result obtained from procedure */ 00098 char *flagValue; /* To store the value read from the flag */ 00099 00100 /* Read the value from the flag */ 00101 flagValue = Cmd_FlagReadByName("residue_layer_schedule"); 00102 if (flagValue == NIL(char)) { 00103 layerMethod = ResDefaultScheduleLayerMethod_c; 00104 } 00105 else { 00106 if (strcmp(flagValue, "asap") == 0) { 00107 layerMethod = ResLayerAsap_c; 00108 } 00109 else if (strcmp(flagValue, "alap") == 0) { 00110 layerMethod = ResLayerAlap_c; 00111 } 00112 else { 00113 (void) fprintf(vis_stderr, "** res error: Unknown method to compute layers."); 00114 (void) fprintf(vis_stderr, "** res error: Assuming default method.\n"); 00115 layerMethod = ResDefaultScheduleLayerMethod_c; 00116 } 00117 } 00118 00119 /* Call the pertinent procedure */ 00120 switch (layerMethod) { 00121 case ResLayerAlap_c: { 00122 result = ComputeCompositionLayersAlap(network, outputArray, ignoreArray); 00123 break; 00124 } 00125 case ResLayerAsap_c: { 00126 result = ComputeCompositionLayersAsap(network, outputArray, ignoreArray); 00127 break; 00128 } 00129 default: { 00130 (void) fprintf(vis_stdout, "** res warning: Layer computation method not implemented."); 00131 (void) fprintf(vis_stdout, "** res warning: Executing default method.\n"); 00132 result = ComputeCompositionLayersAlap(network, outputArray, ignoreArray); 00133 break; 00134 } 00135 } 00136 00137 return result; 00138 } /* End of ResComputeCompositionLayers */ 00139 00140 00155 void 00156 ResLayerPrintInfo(Ntk_Network_t *network, 00157 array_t *layerArray) 00158 { 00159 00160 Ntk_Node_t *nodePtr, *faninNodePtr; /* Node being processed */ 00161 st_table *faninTable; /* Current nodes */ 00162 int layerIndex, newVars; /* index of the layer being processed */ 00163 int i,j; /* For array traversal */ 00164 array_t *currentLayer; /* layer info */ 00165 00166 /* keep track of all nodes that have appeared in the support */ 00167 faninTable = st_init_table(st_ptrcmp, st_ptrhash); 00168 /* Loop over the number of elements in layerArray */ 00169 for (layerIndex = 0; layerIndex < array_n(layerArray); layerIndex++) { 00170 /* reset new variables in the support of this array */ 00171 newVars = 0; 00172 00173 (void) fprintf(vis_stdout, "Layer %d: ", layerIndex); 00174 00175 /* Access the layer info */ 00176 currentLayer = ResLayerFetchIthLayer(layerArray, layerIndex); 00177 00178 /* Print the nodes in a layer that are not PIs */ 00179 LayerForEachNode(currentLayer, i, nodePtr) { 00180 (void) fprintf(vis_stdout, "%s ", Ntk_NodeReadName(nodePtr)); 00181 00182 /* store fanin nodes in the table, keep count */ 00183 Ntk_NodeForEachFanin(nodePtr, j, faninNodePtr) { 00184 if (!st_is_member(faninTable, (char *)faninNodePtr)) { 00185 if (!((Ntk_NodeTestIsLatch(nodePtr) && 00186 (Ntk_NodeTestIsLatchDataInput(faninNodePtr) || 00187 Ntk_NodeTestIsLatchInitialInput(faninNodePtr))) || 00188 Ntk_NodeTestIsConstant(faninNodePtr))) { 00189 00190 st_insert(faninTable, (char *)faninNodePtr, NIL(char)); 00191 newVars++; 00192 } 00193 } 00194 } 00195 } 00196 00197 (void) fprintf(vis_stdout,": SUPPORT = %d", newVars); 00198 (void) fprintf(vis_stdout, "\n"); 00199 00200 00201 } /* End of for every layer */ 00202 00203 /* Clean up */ 00204 st_free_table(faninTable); 00205 return; 00206 } /* End of ResLayerPrintInfo */ 00207 00208 00221 void 00222 ResLayerArrayFree(array_t *layerArray) 00223 { 00224 int i, end; 00225 array_t *currentLayer; 00226 00227 i = 0; 00228 end = array_n(layerArray); 00229 for (i =0; i < end ; i++) { 00230 currentLayer = ResLayerFetchIthLayer(layerArray, i); 00231 LayerFree(currentLayer); 00232 } 00233 array_free(layerArray); 00234 } /* End of ResLayerArrayFree */ 00235 00236 /*---------------------------------------------------------------------------*/ 00237 /* Definition of static functions */ 00238 /*---------------------------------------------------------------------------*/ 00239 00263 static array_t * 00264 ComputeCompositionLayersAsap(Ntk_Network_t *network, 00265 array_t *outputArray, 00266 array_t *ignoreArray) 00267 { 00268 Ntk_Node_t *nodePtr, *faninNodePtr; /* variables to store node pointers */ 00269 int i, j, k; /* iterators */ 00270 st_generator *stGen; /* generator to step through st_table */ 00271 char *key; /* values to read from st_table */ 00272 lsGen listGen; /* list generator to step through nodes */ 00273 array_t *currentLayer, *nextLayer; /* array of nodes belonging to a layer */ 00274 array_t *layerArray; /* array of layers */ 00275 st_table *fanoutCountTable; /* table to store fanout counts of each 00276 * node 00277 */ 00278 int fanoutCount; /* variable to store fanout count of a 00279 * node 00280 */ 00281 int value; /* to read value off the st_table */ 00282 st_table *visitedTable; /* table to store visited nodes */ 00283 00284 /* create a fanout count table starting with all nodes except PIs, 00285 * constant node or a shadow node for any node but a latch(counts as 00286 * comb output). 00287 */ 00288 fanoutCountTable = st_init_table(st_ptrcmp, st_ptrhash); 00289 Ntk_NetworkForEachNode(network, listGen, nodePtr) { 00290 /* does not nodes like PIs, shadow nodes, constants, undefined 00291 * nodes to compute the fanouts, since they do not have to be 00292 * composed into the circuit. 00293 */ 00294 if ((Ntk_NodeTestIsCombOutput(nodePtr)) || 00295 (!(Ntk_NodeTestIsCombInput(nodePtr) || 00296 Ntk_NodeTestIsConstant(nodePtr) || 00297 Ntk_NodeTestIsUndefined(nodePtr) || 00298 Ntk_NodeTestIsShadow(nodePtr)))) { 00299 st_insert(fanoutCountTable, (char *)nodePtr, 00300 (char *)(long)Ntk_NodeReadNumFanouts(nodePtr)); 00301 } 00302 } 00303 00304 /* take out outputs in directly verified table, if so desired */ 00305 /* Assume ignore table has node pointers , reduce fanout count of 00306 * transitive fanin of these nodes 00307 */ 00308 if (ignoreArray != NULL) { 00309 visitedTable = st_init_table(st_ptrcmp, st_ptrhash); 00310 arrayForEachItem(Ntk_Node_t *, ignoreArray, i, nodePtr) { 00311 /* each key is an output node */ 00312 RecursiveDecrementFanoutCount(nodePtr, fanoutCountTable, visitedTable); 00313 } 00314 st_free_table(visitedTable); 00315 00316 /* remove all nodes that are primary inputs and those with fanout 00317 * count 0 providing they are not primary outputs/ or latch inputs 00318 * or latch initial values. 00319 */ 00320 st_foreach_item_int(fanoutCountTable, stGen, &key, &value) { 00321 fanoutCount = value; 00322 nodePtr = (Ntk_Node_t *)key; 00323 assert(fanoutCount >= -1); 00324 if ((!Ntk_NodeTestIsCombOutput(nodePtr)) 00325 && (fanoutCount <= 0)) { 00326 /* delete the item corresponding to fanoutCount i.e. value */ 00327 st_delete_int(fanoutCountTable, (char **)&key, &value); 00328 } 00329 } 00330 /* remove all outputs that belong to ignore outputs */ 00331 arrayForEachItem(Ntk_Node_t *, ignoreArray, i, nodePtr) { 00332 st_delete_int(fanoutCountTable, &nodePtr, &value); 00333 } 00334 } 00335 00336 /* start preparing the layer array */ 00337 layerArray = array_alloc(array_t *, 0); 00338 currentLayer = LayerCreateEmptyLayer(); 00339 00340 /* outputs form the first layer */ 00341 Ntk_NetworkForEachCombOutput(network, listGen, nodePtr) { 00342 if (st_lookup_int(fanoutCountTable, (char *)nodePtr, &fanoutCount)) { 00343 /* insert all outputs that aren't to be ignored in the first layer of the 00344 * layer array 00345 */ 00346 LayerAddNodeAtEnd(currentLayer, nodePtr); 00347 } 00348 } 00349 00350 /* if current layer is not empty */ 00351 while (ResLayerNumNodes(currentLayer) ) { 00352 /* insert current layer into layer array */ 00353 array_insert_last(array_t *, layerArray, currentLayer); 00354 nextLayer = LayerCreateEmptyLayer(); 00355 LayerForEachNode(currentLayer, i, nodePtr) { 00356 Ntk_NodeForEachFanin(nodePtr, j, faninNodePtr) { 00357 /* do not want to get the fanin for latch outputs */ 00358 if(!(Ntk_NodeTestIsConstant(nodePtr) || 00359 (Ntk_NodeTestIsLatch(nodePtr) && 00360 (Ntk_NodeTestIsLatchDataInput(faninNodePtr) || 00361 Ntk_NodeTestIsLatchInitialInput(faninNodePtr))))) { 00362 if (!st_lookup_int(fanoutCountTable, (char *)faninNodePtr, 00363 &fanoutCount)) { 00364 /* maybe it is a PI or constant node */ 00365 if (!(Ntk_NodeTestIsCombInput(faninNodePtr) || 00366 Ntk_NodeTestIsConstant(faninNodePtr) || 00367 Ntk_NodeTestIsUndefined(faninNodePtr) || 00368 Ntk_NodeTestIsShadow(faninNodePtr))) { 00369 error_append("Fanin node %s should have been in table"); 00370 error_append(Ntk_NodeReadName(faninNodePtr)); 00371 /* Cleanup */ 00372 arrayForEachItem(array_t *, layerArray, k, currentLayer) { 00373 LayerFree(currentLayer); 00374 } 00375 array_free(layerArray); 00376 return NIL(array_t); 00377 } /* node is neither PI nor constant */ 00378 } else { /* node is found in table */ 00379 fanoutCount--; 00380 /* decrement fanout count, will go into a later layer */ 00381 if (fanoutCount == 0) { 00382 /* 00383 * it is ready to be put in the array, 00384 * since its fanout count is 1 00385 */ 00386 LayerAddNodeAtEnd(nextLayer, faninNodePtr); 00387 } else if (fanoutCount > 0) { 00388 /* insert new decremented value in table */ 00389 st_insert(fanoutCountTable, (char *)faninNodePtr, 00390 (char *)(long)fanoutCount); 00391 00392 } /* end of nodes fanout count larger than 1 */ 00393 } /* end of fanin node found in fanout count table */ 00394 } /* do not want to get the fanin for latch outputs */ 00395 } /* end of iteration through all the fanin nodes of current node */ 00396 } /* end of iteration through all the nodes of current layer */ 00397 /* the fanout count ensures unique entry of elements ????*/ 00398 currentLayer = nextLayer; 00399 } /* end of while some nodes in current layer */ 00400 00401 /* the loop always exits with an empty array */ 00402 LayerFree(currentLayer); 00403 st_free_table(fanoutCountTable); 00404 if (array_n(layerArray) == 0) { 00405 array_free(layerArray); 00406 layerArray = NIL(array_t); 00407 } 00408 00409 return (layerArray); 00410 00411 } /* End of ComputeCompositionLayersAsap */ 00412 00444 static array_t * 00445 ComputeCompositionLayersAlap(Ntk_Network_t *network, 00446 array_t *outputArray, 00447 array_t *ignoreArray) 00448 { 00449 Ntk_Node_t *nodePtr; /* node being processed */ 00450 array_t *layerArray; /* array of layers */ 00451 array_t *currentLayer; /* layer of nodes */ 00452 st_table *nodeLabelling; /* labeling of a node, its farthest distance 00453 * from the primary input 00454 */ 00455 int numLayers; /* Number of Layers */ 00456 int layerIndex; /* index of a layer (from the primary output */ 00457 int arrayIndex; /* iterator */ 00458 st_generator *stGen; /* generator to step through table */ 00459 char *key; /* values to read from table */ 00460 int value; /* integer value to read from the table */ 00461 00462 /* Initialize the labeling table */ 00463 nodeLabelling = ComputeTransitiveFanin(outputArray); 00464 00465 /* Compute the labeling of the nodes */ 00466 numLayers = ComputeAlapLabelling(network, nodeLabelling); 00467 00468 /* Create the layerArray structure */ 00469 layerArray = array_alloc(array_t *, numLayers); 00470 /* initialize layers */ 00471 for (layerIndex = 0; layerIndex < numLayers; layerIndex++) { 00472 currentLayer = LayerCreateEmptyLayer(); 00473 array_insert(array_t *, layerArray, layerIndex, currentLayer); 00474 } /* end of for */ 00475 00476 /* insert elements of the st_table in the layers */ 00477 st_foreach_item_int(nodeLabelling, stGen, &key, &value) { 00478 layerIndex = value; 00479 nodePtr = (Ntk_Node_t *)key; 00480 /* don't put PIs or comb inputs or constants or undefined 00481 * nodes in layer array 00482 */ 00483 if ((Ntk_NodeTestIsCombOutput(nodePtr)) || 00484 ((layerIndex > 0) && 00485 !(Ntk_NodeTestIsCombInput(nodePtr) || 00486 Ntk_NodeTestIsConstant(nodePtr) || 00487 Ntk_NodeTestIsUndefined(nodePtr) || 00488 Ntk_NodeTestIsShadow(nodePtr)))) { 00489 /* the layers are arranged in reverse order of their farthest 00490 * distance from the node. Hence each node is inserted into 00491 * the numLayers-1-layerIndex. Nodes with layerIndex should be 00492 * put in the last array since they are probably constants 00493 * at the primary outputs or latch initial value. LayerIndex 00494 * could be 0 for primary outputs if it does not appear in the 00495 * transitive fanin of the comb inputs. 00496 */ 00497 if (layerIndex == 0) { 00498 arrayIndex = 0; 00499 assert(Ntk_NodeTestIsCombOutput(nodePtr) == 1); 00500 } else { 00501 arrayIndex = numLayers - layerIndex; 00502 } 00503 currentLayer = array_fetch(array_t *, layerArray, arrayIndex); 00504 LayerAddNodeAtEnd(currentLayer, nodePtr); 00505 } 00506 } 00507 /* Clean up */ 00508 st_free_table(nodeLabelling); 00509 00510 00511 return layerArray; 00512 } /* End of ComputeCompositionLayersAlap */ 00513 00514 00531 static int 00532 ComputeAlapLabelling(Ntk_Network_t *network, 00533 st_table *nodeLabelling) 00534 { 00535 Ntk_Node_t *nodePtr; /* Node being processed */ 00536 lsGen gen; /* For list traversal */ 00537 int numLayers; /* To return as result */ 00538 int outputDepth; /* Depth of the output being processed */ 00539 00540 assert(nodeLabelling != NIL(st_table)); 00541 00542 /* For primary inputs in the table (those not in the table 00543 * are in the transitive fanin of the ignored outputs only 00544 */ 00545 Ntk_NetworkForEachCombInput(network, gen, nodePtr) { 00546 /* do it for fanouts that are in table only */ 00547 if (st_is_member(nodeLabelling, (char *)nodePtr)) { 00548 ComputeAlapLabellingRecur(nodePtr, nodeLabelling); 00549 } 00550 } 00551 00552 /* Compute the number of layers */ 00553 numLayers = 0; 00554 Ntk_NetworkForEachCombOutput(network, gen, nodePtr) { 00555 /* only those outputs not be to be ignored */ 00556 if (st_lookup_int(nodeLabelling, (char *)nodePtr, &outputDepth)) { 00557 if (outputDepth > numLayers ) { 00558 numLayers = outputDepth; 00559 } /* End of if */ 00560 } 00561 } 00562 00563 return numLayers; 00564 } /* End of ComputeAlapLabelling */ 00565 00582 static void 00583 ComputeAlapLabellingRecur(Ntk_Node_t *node, 00584 st_table *nodeLabelling) 00585 { 00586 Ntk_Node_t *fanoutPtr; 00587 int nodeDepth; 00588 int fanoutDepth; 00589 int i; 00590 00591 /* Trivial case */ 00592 if (Ntk_NodeReadNumFanouts(node) == 0) { 00593 return; 00594 } /* End of if */ 00595 00596 /* Look up information for the current node */ 00597 st_lookup_int(nodeLabelling, (char *)node, &nodeDepth); 00598 00599 /* Iterate over its fanouts */ 00600 Ntk_NodeForEachFanout(node, i, fanoutPtr) { 00601 /* Do not process as soon as an input is found beyond an output */ 00602 if (!((Ntk_NodeTestIsLatchDataInput(node) || 00603 Ntk_NodeTestIsLatchInitialInput(node)) && 00604 Ntk_NodeTestIsLatch(fanoutPtr))) { 00605 if (st_is_member(nodeLabelling, (char *)fanoutPtr)) { 00606 /* Look up information for the fanout */ 00607 st_lookup_int(nodeLabelling, (char *)fanoutPtr, &fanoutDepth); 00608 /* If the fanout depth needs to be modified, do so, and recur */ 00609 if (nodeDepth >= fanoutDepth) { 00610 st_insert(nodeLabelling, (char *)fanoutPtr, 00611 (char *)(long)(nodeDepth + 1)); 00612 ComputeAlapLabellingRecur(fanoutPtr, nodeLabelling); 00613 } /* End of if */ 00614 } /* End of if */ 00615 } /* End of if */ 00616 } /* End of for each fanout */ 00617 00618 return; 00619 } /* End of ComputeAlapLabellingRecur */ 00620 00621 00637 static st_table * 00638 ComputeTransitiveFanin(array_t *outputArray) 00639 { 00640 Ntk_Node_t *nodePtr; 00641 st_table * faninTable; 00642 int i; 00643 00644 faninTable = st_init_table(st_ptrcmp, st_ptrhash); 00645 arrayForEachItem(Ntk_Node_t *, outputArray, i, nodePtr) { 00646 ComputeTransitiveFaninRecur(nodePtr, faninTable); 00647 } 00648 return faninTable; 00649 } /* End of ComputeTransitiveFanin */ 00650 00666 static void 00667 ComputeTransitiveFaninRecur(Ntk_Node_t *nodePtr, 00668 st_table *faninTable) 00669 { 00670 Ntk_Node_t *faninNodePtr; 00671 int i; 00672 00673 if (st_lookup(faninTable, (char *)nodePtr, NIL(char *))) { 00674 return; 00675 } 00676 00677 00678 /* recur on fanin nodes */ 00679 Ntk_NodeForEachFanin(nodePtr, i, faninNodePtr) { 00680 /* Test this case cos other comb inputs have no fanins */ 00681 if (!((Ntk_NodeTestIsLatchDataInput(faninNodePtr) || 00682 Ntk_NodeTestIsLatchInitialInput(faninNodePtr)) && 00683 Ntk_NodeTestIsLatch(nodePtr))) { 00684 ComputeTransitiveFaninRecur(faninNodePtr, faninTable); 00685 } /* end of if */ 00686 } /* iterate over all fanins */ 00687 00688 st_insert(faninTable, (char *)nodePtr, NIL(char)); 00689 return; 00690 00691 } /* End of ComputeTransitiveFaninRecur */ 00692 00707 static void 00708 RecursiveDecrementFanoutCount(Ntk_Node_t *nodePtr, 00709 st_table *fanoutCountTable, 00710 st_table *visitedTable) 00711 { 00712 Ntk_Node_t *faninNodePtr; 00713 int i, fanoutCount; 00714 00715 /* the following kinds of nodes will not be in the table. */ 00716 if ((!Ntk_NodeTestIsCombOutput(nodePtr)) && 00717 (Ntk_NodeTestIsCombInput(nodePtr) || 00718 Ntk_NodeTestIsUndefined(nodePtr)|| 00719 Ntk_NodeTestIsConstant(nodePtr) || 00720 Ntk_NodeTestIsShadow(nodePtr))) { 00721 return; 00722 } 00723 /* all nodes called here should exist in table */ 00724 if (!st_lookup_int(fanoutCountTable, (char *)nodePtr, &fanoutCount)){ 00725 error_append("Node "); 00726 error_append(Ntk_NodeReadName(nodePtr)); 00727 error_append(" should have been in table\n"); 00728 return; 00729 } 00730 00731 fanoutCount--; 00732 /* reduce fanout count of node */ 00733 st_insert(fanoutCountTable, (char *)nodePtr, (char *)(long)fanoutCount); 00734 /* if this node is visited, decrement its fanout but do not proceed 00735 * any further (i.e. do not proceed with its fanins 00736 */ 00737 if (st_is_member(visitedTable, (char *)nodePtr)) { 00738 return; 00739 } else { 00740 st_insert(visitedTable, (char *)nodePtr, NIL(char)); 00741 00742 /* 00743 * recur with fanin nodes except nodes with no fanins (that arent in table) 00744 * and latch outputs 00745 */ 00746 Ntk_NodeForEachFanin(nodePtr, i, faninNodePtr) { 00747 /* may be a redundant test, since it will pop out in the first line of 00748 * the procedure anyways. 00749 */ 00750 if (!(Ntk_NodeTestIsConstant(faninNodePtr) || 00751 ((Ntk_NodeTestIsLatchDataInput(faninNodePtr) || 00752 Ntk_NodeTestIsLatchInitialInput(faninNodePtr)) && 00753 Ntk_NodeTestIsLatch(nodePtr)))) { 00754 RecursiveDecrementFanoutCount(faninNodePtr, fanoutCountTable, visitedTable); 00755 } 00756 } /* end of iterating over fanins */ 00757 } /* end of else if not visited */ 00758 return; 00759 } /* End of RecursiveDecrementFanoutCount */