VIS

src/ord/ordNodes.c

Go to the documentation of this file.
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 }