VIS
|
00001 00037 #include "ordInt.h" 00038 00039 static char rcsid[] UNUSED = "$Id: ordNodes.c,v 1.12 2005/04/16 06:15:25 fabio Exp $"; 00040 00041 /*---------------------------------------------------------------------------*/ 00042 /* Constant declarations */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 00046 /*---------------------------------------------------------------------------*/ 00047 /* Type declarations */ 00048 /*---------------------------------------------------------------------------*/ 00049 00050 00051 /*---------------------------------------------------------------------------*/ 00052 /* Structure declarations */ 00053 /*---------------------------------------------------------------------------*/ 00061 typedef struct OrderingStateStruct { 00062 st_table *nodeToOrderList; /* Ntk_Node_t * to lsList; top. order of tfi 00063 nodes */ 00064 st_table *from; /* Ntk_Node_t * to Ntk_Node_t */ 00065 lsGen last; /* insertion point */ 00066 Ntk_Node_t *root; /* current output */ 00067 } OrderingState_t; 00068 00069 /*---------------------------------------------------------------------------*/ 00070 /* Variable declarations */ 00071 /*---------------------------------------------------------------------------*/ 00072 00073 00074 /*---------------------------------------------------------------------------*/ 00075 /* Macro declarations */ 00076 /*---------------------------------------------------------------------------*/ 00077 00078 00081 /*---------------------------------------------------------------------------*/ 00082 /* Static function prototypes */ 00083 /*---------------------------------------------------------------------------*/ 00084 00085 static lsList NetworkOrderTFIOfRootsByMerging(Ntk_Network_t *network, lsList roots, Ord_ListMergeMethod method, st_table *nodeToHandle, int verbose); 00086 static lsList NodeOrderRecursivelyByMerging(Ntk_Node_t * node, OrderingState_t * orderingState, Ord_ListMergeMethod method, int verbose); 00087 static lsList NetworkOrderTFIOfRootsByAppending(Ntk_Network_t *network, lsList roots, st_table *nodeToHandle, int verbose); 00088 static void NodeOrderRecursivelyByAppending(Ntk_Node_t * node, lsList orderList, st_table *nodeToHandle, int verbose); 00089 static lsList NetworkOrderTFIOfRootsByInterleaving(Ntk_Network_t *network, lsList roots, st_table *nodeToHandle, int verbose); 00090 static void NodeOrderRecursivelyByInterleaving(Ntk_Node_t * node, lsList orderList, st_table *nodeToHandle, OrderingState_t *orderingState, int verbose); 00091 static OrderingState_t * NetworkInitializeOrderingState(Ntk_Network_t * network); 00092 static void OrderingStateSetLast(Ntk_Node_t * node, st_table * nodeToHandle, OrderingState_t * orderingState); 00093 static void OrderingStateFree(OrderingState_t * orderingState); 00094 static lsList NodeReadOrderList(Ntk_Node_t * node, OrderingState_t * orderingState); 00095 static void NodeSetOrderList(Ntk_Node_t * node, lsList orderList, OrderingState_t * orderingState); 00096 static Ntk_Node_t * NodeReadFrom(Ntk_Node_t * node, OrderingState_t * orderingState); 00097 static void NodeSetFrom(Ntk_Node_t * node, OrderingState_t * orderingState); 00098 00102 /*---------------------------------------------------------------------------*/ 00103 /* Definition of exported functions */ 00104 /*---------------------------------------------------------------------------*/ 00105 00106 00107 /*---------------------------------------------------------------------------*/ 00108 /* Definition of internal functions */ 00109 /*---------------------------------------------------------------------------*/ 00110 00137 lsList 00138 OrdNetworkOrderTFIOfRoots( 00139 Ntk_Network_t *network, 00140 lsList roots /* of Ntk_Node_t */, 00141 Ord_NodeMethod nodeOrderMethod, 00142 st_table *nodeToHandle /* modified */, 00143 int verbose) 00144 { 00145 switch (nodeOrderMethod) { 00146 case Ord_NodesByDefault_c: 00147 case Ord_NodesByInterleaving_c: 00148 return NetworkOrderTFIOfRootsByInterleaving(network, roots, 00149 nodeToHandle, verbose); 00150 case Ord_NodesByMergingLeft_c: 00151 return NetworkOrderTFIOfRootsByMerging(network, roots, 00152 Ord_ListMergeLeft_c, 00153 nodeToHandle, verbose); 00154 case Ord_NodesByMergingRight_c: 00155 return NetworkOrderTFIOfRootsByMerging(network, roots, 00156 Ord_ListMergeRight_c, 00157 nodeToHandle, verbose); 00158 case Ord_NodesByAppending_c: 00159 return NetworkOrderTFIOfRootsByAppending(network, roots, 00160 nodeToHandle, verbose); 00161 default: 00162 fail("unrecognized node ordering method"); 00163 return (lsList) 0; 00164 } 00165 } 00166 00167 00168 /*---------------------------------------------------------------------------*/ 00169 /* Definition of static functions */ 00170 /*---------------------------------------------------------------------------*/ 00171 00203 static lsList 00204 NetworkOrderTFIOfRootsByMerging( 00205 Ntk_Network_t *network, 00206 lsList roots /* list of Ntk_Node_t */, 00207 Ord_ListMergeMethod method, 00208 st_table *nodeToHandle /* modified */, 00209 int verbose) 00210 { 00211 lsGen gen; 00212 Ntk_Node_t *root; 00213 OrderingState_t *orderingState; 00214 lsList orderList = lsCreate(); /* return list */ 00215 00216 00217 /* 00218 * Compute and store the depth of each node in the network. (The depth of a 00219 * node is stored in the undef field of the node). 00220 */ 00221 OrdNetworkComputeNodeDepths(network, roots); 00222 00223 /* 00224 * Initialize the necessary state needed for recursing through the network. 00225 */ 00226 orderingState = NetworkInitializeOrderingState(network); 00227 00228 /* 00229 * For each root, recursively order all nodes in its transitive fanin, and 00230 * merge this ordering into the nodes already ordered. 00231 */ 00232 lsForEachItem(roots, gen, root) { 00233 lsList rootOrderList = NodeOrderRecursivelyByMerging(root, orderingState, 00234 method, verbose); 00235 Ord_ListMergeListUsingTable(orderList, rootOrderList, nodeToHandle, method); 00236 00237 if (verbose > 2) { 00238 /* This can generate a lot of output. */ 00239 (void) fprintf(vis_stdout, "\nOrder list after merging node %s\n", 00240 Ntk_NodeReadName(root)); 00241 OrdNodeListWrite(vis_stdout, orderList); 00242 } 00243 } 00244 00245 /* 00246 * Clean up and return the ordering list. 00247 */ 00248 OrderingStateFree(orderingState); 00249 return orderList; 00250 } 00251 00252 00268 static lsList 00269 NodeOrderRecursivelyByMerging( 00270 Ntk_Node_t * node, 00271 OrderingState_t * orderingState, 00272 Ord_ListMergeMethod method, 00273 int verbose) 00274 { 00275 lsList orderList; 00276 00277 00278 /* 00279 * If node has already been visited (i.e. its orderList is non-NULL), then 00280 * just return the orderList already computed. 00281 */ 00282 orderList = NodeReadOrderList(node, orderingState); 00283 if (orderList != (lsList) NULL) { 00284 return orderList; 00285 } 00286 00287 /* 00288 * Node has not yet been visited. Create the orderList for node. 00289 */ 00290 if (Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsConstant(node)) { 00291 /* 00292 * Combinational inputs and constants terminate the recursion. If node is 00293 * one of these, then just create an empty list, to which we will add the 00294 * node. 00295 */ 00296 orderList = lsCreate(); 00297 } 00298 else if (Ntk_NodeReadNumFanins(node) == 1) { 00299 /* 00300 * If there is just one fanin, then just make a copy of the the fanin's 00301 * orderList. This case is distinguished from the general case for 00302 * efficiency. 00303 */ 00304 lsList faninOrderList = NodeOrderRecursivelyByMerging(Ntk_NodeReadFaninNode(node, 0), 00305 orderingState, 00306 method, verbose); 00307 orderList = lsCopy(faninOrderList, (lsGeneric (*) (lsGeneric)) NULL); 00308 } 00309 else { 00310 int i; 00311 array_t *sortedFanins; 00312 st_table *nodeToHandle; 00313 00314 /* 00315 * Sort the fanins of node in decreasing order of depth. See 00316 * OrdNetworkComputeNodeDepths. 00317 */ 00318 sortedFanins = array_dup(Ntk_NodeReadFanins(node)); 00319 array_sort(sortedFanins, OrdNodesFromArrayCompareDepth); 00320 00321 /* 00322 * Start with an empty list for the orderList of the node. Also, start 00323 * with an empty nodeToHandle table. This table is only used locally, and 00324 * will be deleted below. 00325 */ 00326 orderList = lsCreate(); 00327 nodeToHandle = st_init_table(st_ptrcmp, st_ptrhash); 00328 00329 /* 00330 * Recursively visit the fanins in order of decreasing depth. The 00331 * nodeToHandle table keeps track of the nodes currently in orderList. 00332 */ 00333 for (i = 0; i < array_n(sortedFanins); i++) { 00334 Ntk_Node_t *fanin = array_fetch(Ntk_Node_t *, sortedFanins, i); 00335 lsList faninOrderList = NodeOrderRecursivelyByMerging(fanin, 00336 orderingState, 00337 method, verbose); 00338 /* 00339 * Merge faninOrderList into the list of nodes already ordered. 00340 */ 00341 Ord_ListMergeListUsingTable(orderList, faninOrderList, nodeToHandle, method); 00342 } 00343 array_free(sortedFanins); 00344 st_free_table(nodeToHandle); 00345 } 00346 00347 /* 00348 * Regardless of the branch taken above, add node to the end of the 00349 * orderList, and set the node's orderList. 00350 */ 00351 (void) lsNewEnd(orderList, (lsGeneric) node, LS_NH); 00352 NodeSetOrderList(node, orderList, orderingState); 00353 00354 if (verbose > 2) { 00355 /* This can generate a lot of output. */ 00356 (void) fprintf(vis_stdout, "\nOrder list for node %s\n", Ntk_NodeReadName(node)); 00357 OrdNodeListWrite(vis_stdout, orderList); 00358 } 00359 00360 return orderList; 00361 } 00362 00363 00383 static lsList 00384 NetworkOrderTFIOfRootsByAppending( 00385 Ntk_Network_t *network, 00386 lsList roots /* list of Ntk_Node_t */, 00387 st_table *nodeToHandle /* modified */, 00388 int verbose) 00389 { 00390 lsGen gen; 00391 Ntk_Node_t *root; 00392 lsList orderList = lsCreate(); /* return list */ 00393 00394 00395 /* 00396 * Compute and store the depth of each node in the network. (The depth of a 00397 * node is stored in the undef field of the node). 00398 */ 00399 OrdNetworkComputeNodeDepths(network, roots); 00400 00401 if (verbose > 1) { 00402 Ntk_Node_t *node; 00403 (void) fprintf(vis_stdout, "\nDepths of network nodes:\n"); 00404 Ntk_NetworkForEachNode(network, gen, node) { 00405 (void) fprintf(vis_stdout, "%s: depth = %ld\n", Ntk_NodeReadName(node), 00406 OrdNodeReadDepth(node)); 00407 } 00408 } 00409 00410 /* 00411 * For each root, recursively order all nodes in its transitive fanin. 00412 */ 00413 lsForEachItem(roots, gen, root) { 00414 NodeOrderRecursivelyByAppending(root, orderList, nodeToHandle, verbose); 00415 } 00416 00417 return orderList; 00418 } 00419 00420 00438 static void 00439 NodeOrderRecursivelyByAppending( 00440 Ntk_Node_t * node, 00441 lsList orderList, 00442 st_table *nodeToHandle, 00443 int verbose) 00444 { 00445 lsHandle handle; 00446 00447 /* 00448 * If node has already been visited (i.e. its in the nodeToHandle table), then 00449 * just return. 00450 */ 00451 if (st_is_member(nodeToHandle, (char *) node)) { 00452 return; 00453 } 00454 00455 /* 00456 * Node has not yet been visited. Recurse on the inputs, and then add node 00457 * to the end of the current ordering. 00458 */ 00459 if (!(Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsConstant(node))) { 00460 /* 00461 * Combinational inputs and constants terminate the recursion. If node is 00462 * not one of these, then recurse on the inputs. 00463 */ 00464 int i; 00465 array_t *sortedFanins; 00466 00467 /* 00468 * Sort the fanins of node in decreasing order of depth. See 00469 * OrdNetworkComputeNodeDepths. 00470 */ 00471 sortedFanins = array_dup(Ntk_NodeReadFanins(node)); 00472 array_sort(sortedFanins, OrdNodesFromArrayCompareDepth); 00473 00474 /* 00475 * Recursively visit the fanins in order of decreasing depth. The 00476 * nodeToHandle table keeps track of the nodes currently in orderList. 00477 */ 00478 for (i = 0; i < array_n(sortedFanins); i++) { 00479 Ntk_Node_t *fanin = array_fetch(Ntk_Node_t *, sortedFanins, i); 00480 00481 NodeOrderRecursivelyByAppending(fanin, orderList, nodeToHandle, verbose); 00482 } 00483 array_free(sortedFanins); 00484 } 00485 00486 /* 00487 * Regardless of the branch taken above, add node to the end of the 00488 * orderList and to the nodeToHandle table. 00489 */ 00490 (void) lsNewEnd(orderList, (lsGeneric) node, &handle); 00491 st_insert(nodeToHandle, (char *) node, (char *) handle); 00492 } 00493 00494 00514 static lsList 00515 NetworkOrderTFIOfRootsByInterleaving( 00516 Ntk_Network_t *network, 00517 lsList roots /* list of Ntk_Node_t */, 00518 st_table *nodeToHandle /* modified */, 00519 int verbose) 00520 { 00521 lsGen gen; 00522 Ntk_Node_t *root; 00523 lsList orderList = lsCreate(); /* return list */ 00524 OrderingState_t *orderingState; 00525 00526 /* 00527 * Compute and store the depth of each node in the network. (The depth of a 00528 * node is stored in the undef field of the node.) 00529 */ 00530 OrdNetworkComputeNodeDepths(network, roots); 00531 00532 /* 00533 * Initialize the state needed for recurring through the network. 00534 */ 00535 orderingState = NetworkInitializeOrderingState(network); 00536 00537 if (verbose > 1) { 00538 Ntk_Node_t *node; 00539 (void) fprintf(vis_stdout, "\nDepths of network nodes:\n"); 00540 Ntk_NetworkForEachNode(network, gen, node) { 00541 (void) fprintf(vis_stdout, "%s: depth = %ld\n", Ntk_NodeReadName(node), 00542 OrdNodeReadDepth(node)); 00543 } 00544 } 00545 00546 /* 00547 * For each root, recursively order all nodes in its transitive fanin. 00548 */ 00549 lsForEachItem(roots, gen, root) { 00550 orderingState->root = root; 00551 orderingState->last = lsStart(orderList); 00552 NodeOrderRecursivelyByInterleaving(root, orderList, nodeToHandle, 00553 orderingState, verbose); 00554 lsFinish(orderingState->last); 00555 00556 if (verbose > 2) { 00557 /* This can generate a lot of output. */ 00558 (void) fprintf(vis_stdout, "\nOrder list after merging node %s\n", 00559 Ntk_NodeReadName(root)); 00560 OrdNodeListWrite(vis_stdout, orderList); 00561 } 00562 } 00563 00564 /* 00565 * Clean up and return the ordering list. 00566 */ 00567 OrderingStateFree(orderingState); 00568 return orderList; 00569 } 00570 00571 00589 static void 00590 NodeOrderRecursivelyByInterleaving( 00591 Ntk_Node_t * node, 00592 lsList orderList, 00593 st_table *nodeToHandle, 00594 OrderingState_t *orderingState, 00595 int verbose) 00596 { 00597 lsHandle handle; 00598 00599 /* 00600 * If node has already been visited (i.e., it is in the nodeToHandle table), 00601 * then update the info on the output from which it was last reached, 00602 * and change the insertion point to this node. 00603 */ 00604 if (st_is_member(nodeToHandle, (char *) node)) { 00605 if (NodeReadFrom(node, orderingState) != orderingState->root) { 00606 OrderingStateSetLast(node, nodeToHandle, orderingState); 00607 NodeSetFrom(node, orderingState); 00608 } 00609 return; 00610 } 00611 00612 /* 00613 * Node has not yet been visited. Recur on the inputs, and then add node 00614 * to the end of the current ordering. 00615 */ 00616 if (!(Ntk_NodeTestIsCombInput(node) || Ntk_NodeTestIsConstant(node))) { 00617 /* 00618 * Combinational inputs and constants terminate the recursion. If node is 00619 * not one of these, then recur on the inputs. 00620 */ 00621 int i; 00622 array_t *sortedFanins; 00623 00624 /* 00625 * Sort the fanins of node in decreasing order of depth. See 00626 * OrdNetworkComputeNodeDepths. 00627 */ 00628 sortedFanins = array_dup(Ntk_NodeReadFanins(node)); 00629 array_sort(sortedFanins, OrdNodesFromArrayCompareDepth); 00630 00631 /* 00632 * Recursively visit the fanins in order of decreasing depth. The 00633 * nodeToHandle table keeps track of the nodes currently in orderList. 00634 */ 00635 for (i = 0; i < array_n(sortedFanins); i++) { 00636 Ntk_Node_t *fanin = array_fetch(Ntk_Node_t *, sortedFanins, i); 00637 00638 NodeOrderRecursivelyByInterleaving(fanin, orderList, nodeToHandle, 00639 orderingState,verbose); 00640 } 00641 array_free(sortedFanins); 00642 } 00643 00644 /* 00645 * Regardless of the branch taken above, add node to orderList at the 00646 * insertion point and to the nodeToHandle table. Make node the new 00647 * insertion point. 00648 */ 00649 NodeSetFrom(node, orderingState); 00650 (void) lsInBefore(orderingState->last, (lsGeneric) node, &handle); 00651 st_insert(nodeToHandle, (char *) node, (char *) handle); 00652 OrderingStateSetLast(node, nodeToHandle, orderingState); 00653 } 00654 00655 00673 static OrderingState_t * 00674 NetworkInitializeOrderingState( 00675 Ntk_Network_t * network) 00676 { 00677 OrderingState_t *orderingState = ALLOC(OrderingState_t, 1); 00678 00679 /* nodeToOrderList is used by the merging method. */ 00680 orderingState->nodeToOrderList = st_init_table(st_ptrcmp, st_ptrhash); 00681 00682 /* from, last, and root used by the interleaving method. */ 00683 orderingState->from = st_init_table(st_ptrcmp, st_ptrhash); 00684 orderingState->last = NULL; 00685 orderingState->root = NULL; 00686 00687 return orderingState; 00688 } 00689 00690 00703 static void 00704 OrderingStateSetLast( 00705 Ntk_Node_t * node, 00706 st_table * nodeToHandle, 00707 OrderingState_t * orderingState) 00708 { 00709 lsHandle handle; 00710 lsGen gen; 00711 lsGeneric data; 00712 00713 /* Dispose of the current generator. */ 00714 lsFinish(orderingState->last); 00715 00716 /* Get a handle for the current node. */ 00717 st_lookup(nodeToHandle, node, &handle); 00718 00719 /* 00720 * Create a new generator positioned after node and register it 00721 * in orderingState. 00722 */ 00723 gen = lsGenHandle(handle,&data,LS_AFTER); 00724 orderingState->last = gen; 00725 } 00726 00736 static void 00737 OrderingStateFree( 00738 OrderingState_t * orderingState) 00739 { 00740 st_generator *stGen; 00741 lsList orderList; 00742 Ntk_Node_t *node; 00743 00744 st_foreach_item(orderingState->nodeToOrderList, stGen, &node, &orderList) { 00745 (void) lsDestroy(orderList, (void (*) (lsGeneric)) NULL); 00746 } 00747 00748 st_free_table(orderingState->nodeToOrderList); 00749 st_free_table(orderingState->from); 00750 00751 FREE(orderingState); 00752 } 00753 00754 00768 static lsList 00769 NodeReadOrderList( 00770 Ntk_Node_t * node, 00771 OrderingState_t * orderingState) 00772 { 00773 lsList orderList = (lsList) NULL; 00774 00775 st_lookup(orderingState->nodeToOrderList, node, &orderList); 00776 00777 return orderList; 00778 } 00779 00780 00790 static void 00791 NodeSetOrderList( 00792 Ntk_Node_t * node, 00793 lsList orderList, 00794 OrderingState_t * orderingState) 00795 { 00796 st_insert(orderingState->nodeToOrderList, (char *) node, (char *) orderList); 00797 } 00798 00799 00813 static Ntk_Node_t * 00814 NodeReadFrom( 00815 Ntk_Node_t * node, 00816 OrderingState_t * orderingState) 00817 { 00818 Ntk_Node_t * from = NULL; 00819 00820 st_lookup(orderingState->from, node, &from); 00821 00822 return from; 00823 } 00824 00825 00835 static void 00836 NodeSetFrom( 00837 Ntk_Node_t * node, 00838 OrderingState_t * orderingState) 00839 { 00840 st_insert(orderingState->from, (char *) node, (char *) orderingState->root); 00841 }