VIS

src/part/partPartial.c

Go to the documentation of this file.
00001 
00027 #include "partInt.h"
00028 
00029 static char rcsid[] UNUSED = "$Id: partPartial.c,v 1.10 2005/04/16 14:52:45 fabio Exp $";
00030 
00031 /*---------------------------------------------------------------------------*/
00032 /* Constant declarations                                                     */
00033 /*---------------------------------------------------------------------------*/
00034 
00035 
00036 /*---------------------------------------------------------------------------*/
00037 /* Structure declarations                                                    */
00038 /*---------------------------------------------------------------------------*/
00039 
00040 
00041 /*---------------------------------------------------------------------------*/
00042 /* Type declarations                                                         */
00043 /*---------------------------------------------------------------------------*/
00044 
00045 
00046 /*---------------------------------------------------------------------------*/
00047 /* Variable declarations                                                     */
00048 /*---------------------------------------------------------------------------*/
00049 
00050 
00051 /*---------------------------------------------------------------------------*/
00052 /* Macro declarations                                                        */
00053 /*---------------------------------------------------------------------------*/
00054 
00055 
00058 /*---------------------------------------------------------------------------*/
00059 /* Static function prototypes                                                */
00060 /*---------------------------------------------------------------------------*/
00061 
00062 
00066 /*---------------------------------------------------------------------------*/
00067 /* Definition of exported functions                                          */
00068 /*---------------------------------------------------------------------------*/
00069 
00070 
00071 /*---------------------------------------------------------------------------*/
00072 /* Definition of internal functions                                          */
00073 /*---------------------------------------------------------------------------*/
00074 
00075 
00086 void
00087 PartPartitionPartial(
00088   Ntk_Network_t *network,
00089   graph_t       *partition,
00090   lsList        rootList,
00091   lsList        leaveList,
00092   mdd_t         *careSet,
00093   lsList        nodeList,
00094   int           inTermsOfCombInputs)
00095 {
00096   Ntk_Node_t     *node;            /* Pointer to iterate over nodes */
00097   Mvf_Function_t *mddFunction;     /* Pointer to a MDD */
00098   mdd_manager    *manager;         /* Mdd manager in the partition */
00099   st_table       *tableOfLeaves;   /* To store the leaves of the graph */
00100   st_table       *mddIdToNodeName; /* For quick lookup of node's name */
00101   array_t        *arrayOfMvf;      /* To store the next state functions */
00102   array_t        *arrayOfRoots;    /* To store the roots of the graph */
00103   lsList         sinkList;         /* Vertices representing comb. outputs */
00104   lsGen          gen;              /* To iterate over lists */
00105   vertex_t       *toVertex;        /* Will hold the current function vertex */
00106   int            i;                /* Index for loops */
00107   long           mddId;            /* Will hold the mddId being processed */
00108   st_table       *mddSupport;      /* To store the support of the Mvf_Function */
00109   st_generator   *stGen;           /* To iterate over the MddIds of the support */
00110   vertex_t       *fromVertex;      /* Will hold the current vertex in the support */
00111   char           *nodeName;
00112   array_t        *singletonMvfArray;
00113   array_t        *singletonArrayOfRoots;
00114   array_t        *tmpArrayOfMvf;
00115   Mvf_Function_t *nodeMvf;
00116   lsList         sortedListOfNodes;     
00117   array_t        *sortedArrayOfPartitionNodes;
00118   array_t        *unsortedArrayOfPartitionNodes;
00119   st_table       *tableOfPartitionNodes;
00120   array_t        *validNodeArray;
00121   array_t        *invalidNodeArray;
00122   int            chars_printed;
00123 
00124   assert(rootList == (lsList)0);
00125   assert(leaveList == (lsList)0);
00126   manager = PartPartitionReadMddManager(partition);
00127   invalidNodeArray = array_alloc(char *, 0);
00128   validNodeArray = array_alloc(char *, 0);
00129   
00130   /* check that nodes in nodeList are valid ones */
00131   lsForEachItem(nodeList, gen, nodeName){
00132     node = Ntk_NetworkFindNodeByName(network, nodeName);
00133     if(node == NIL(Ntk_Node_t)){
00134       array_insert_last(char *, invalidNodeArray, nodeName);
00135     }
00136     else{
00137       array_insert_last(char *, validNodeArray, nodeName);      
00138     }
00139   }
00140   if(array_n(invalidNodeArray) > 0){
00141     fprintf(stdout, "The following node(s) are being ignored in the partition:\n");
00142     chars_printed = 0;
00143     for(i = 0; i < array_n(invalidNodeArray); i++){
00144       fprintf(stdout, "%s ", array_fetch(char *, invalidNodeArray, i));
00145       chars_printed += strlen(array_fetch(char *, invalidNodeArray, i));
00146       if(chars_printed >60){
00147         chars_printed = 0;
00148         fprintf(stdout, "\n");
00149       }
00150     }
00151     fprintf(stdout, "\nThey are either invalid names or have been swept away at \n");
00152     fprintf(stdout, "the end of the flatten_network command. Use <flatten_network -s> \n");
00153     fprintf(stdout, "to avoid performing a sweep after the flatten command, \n");        
00154   }
00155   array_free(invalidNodeArray);
00156   
00157 
00158   /* Make the combinational input  nodes into leaves */
00159   tableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash);
00160   mddIdToNodeName = st_init_table(st_numcmp, st_numhash);
00161   Ntk_NetworkForEachCombInput(network, gen, node) {
00162     st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) );
00163     st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 
00164               Ntk_NodeReadName(node));
00165   }
00166   
00167   /* create temporary array and table of partition nodes */
00168   unsortedArrayOfPartitionNodes = array_alloc(Ntk_Node_t *, 0);  
00169   tableOfPartitionNodes = st_init_table(st_ptrcmp, st_ptrhash);
00170   for(i = 0; i < array_n(validNodeArray); i++){
00171     nodeName = array_fetch(char *, validNodeArray, i);
00172     node = Ntk_NetworkFindNodeByName(network, nodeName);
00173     assert(!Ntk_NodeTestIsShadow(node));
00174     /* make sure that the node is not a CI or CO */
00175     if(!Ntk_NodeTestIsCombInput(node) && !Ntk_NodeTestIsCombOutput(node)){
00176       array_insert_last(Ntk_Node_t *, unsortedArrayOfPartitionNodes, node);
00177       st_insert(tableOfPartitionNodes, (char *) node, (char *) (long) (-1));
00178     }
00179   }
00180   array_free(validNodeArray);
00181 
00182   /* create sorted array of partition nodes */
00183   sortedListOfNodes = Ntk_NetworkComputeTopologicalOrder(network, unsortedArrayOfPartitionNodes, tableOfLeaves);
00184   sortedArrayOfPartitionNodes = array_alloc(Ntk_Node_t *, 0);  
00185   lsForEachItem(sortedListOfNodes, gen, node){
00186     /* sortedListOfNodes includes many internal nodes, need to filter them out */
00187     if(st_is_member(tableOfPartitionNodes, (char *) node)){
00188       array_insert_last(Ntk_Node_t *, sortedArrayOfPartitionNodes, node);      
00189     }   
00190   }
00191   array_free(unsortedArrayOfPartitionNodes);
00192   lsDestroy(sortedListOfNodes, (void (*)(lsGeneric))0);  
00193   st_free_table(tableOfPartitionNodes);
00194       
00195 
00196   /* Create mvfs for nodes in sortedArrayOfPartitionNodes */
00197   tmpArrayOfMvf = array_alloc(Mvf_Function_t *, 0);
00198   for(i=0; i < array_n(sortedArrayOfPartitionNodes); i++){
00199     node = array_fetch(Ntk_Node_t *, sortedArrayOfPartitionNodes, i);
00200     singletonArrayOfRoots = array_alloc(Ntk_Node_t *, 0);
00201     array_insert_last(Ntk_Node_t *, singletonArrayOfRoots, node);
00202     singletonMvfArray = Ntm_NetworkBuildMvfs(network, singletonArrayOfRoots, 
00203                                              tableOfLeaves, careSet);
00204     nodeMvf = array_fetch(Mvf_Function_t *, singletonMvfArray, 0);
00205     array_insert_last(Mvf_Function_t *, tmpArrayOfMvf, nodeMvf);
00206     array_free(singletonMvfArray);
00207     array_free(singletonArrayOfRoots);
00208 
00209     /* now create an mddId for this node, and make it a leaf */
00210     if(inTermsOfCombInputs == 0){
00211       if(Ntk_NodeReadMddId(node) == NTK_UNASSIGNED_MDD_ID){
00212         Ord_NetworkAssignMddIdForNode(network, node);
00213       }
00214       st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) );    
00215       st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 
00216                 Ntk_NodeReadName(node));
00217     }
00218   }
00219 
00220   /* Make the combinational output nodes into roots */
00221   arrayOfRoots = array_alloc(Ntk_Node_t *, 0);
00222   Ntk_NetworkForEachCombOutput(network, gen, node) {
00223     array_insert_last(Ntk_Node_t *, arrayOfRoots, node);
00224   }
00225 
00226   /* build mvfs of nodes in arrayOfMvf in terms of partition nodes and comb inputs */
00227   arrayOfMvf = Ntm_NetworkBuildMvfs(network, arrayOfRoots, tableOfLeaves, 
00228                                     careSet);
00229   array_append(arrayOfRoots, sortedArrayOfPartitionNodes);
00230   array_append(arrayOfMvf, tmpArrayOfMvf);
00231   array_free(sortedArrayOfPartitionNodes);
00232   array_free(tmpArrayOfMvf);
00233 
00234   /* Create one vertex for every component of arrayOfMvf */
00235   for (i=0; i < array_n(arrayOfRoots); i++) {
00236     node = array_fetch(Ntk_Node_t *, arrayOfRoots, i);
00237     mddId = (long) Ntk_NodeReadMddId(node);
00238 
00239     /* obtain the function attached to the node */
00240     mddFunction = array_fetch(Mvf_Function_t *, arrayOfMvf, i);
00241     toVertex = g_add_vertex(partition);
00242     
00243     /* Update the look-up tables in the graph */
00244     st_insert(PartPartitionReadNameToVertex(partition),
00245               Ntk_NodeReadName(node), (char *)toVertex);
00246     if (mddId != -1) {
00247       st_insert(PartPartitionReadMddIdToVertex(partition),
00248                 (char *)mddId, (char *)toVertex);
00249     } 
00250     toVertex->user_data = 
00251       (gGeneric)PartVertexInfoCreateSingle(Ntk_NodeReadName(node), 
00252                                            mddFunction, 
00253                                            (int) mddId);
00254   } 
00255   
00256   /* Read the list of vertices on the graph */
00257   sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0);
00258 
00259   /* 
00260    * For every function on every combinational output, compute the
00261    * support and create vertices in the graph when needed 
00262    */
00263   lsForEachItem(sinkList, gen, toVertex) {
00264     mddFunction = PartVertexReadFunction(toVertex);
00265     mddSupport = PartCreateFunctionSupportTable(mddFunction);
00266 
00267     /* 
00268      * Create one edge (and one vertex if necessary) for every element
00269      * in mddSupport 
00270      */
00271     st_foreach_item(mddSupport, stGen, &mddId, NULL) {
00272       char *name;
00273 
00274       /* Create vertex with the information if needed */
00275       if (st_lookup(PartPartitionReadMddIdToVertex(partition), 
00276                     (char *)mddId, &fromVertex) == 0) {
00277         fromVertex = g_add_vertex(partition);
00278         
00279         st_lookup(mddIdToNodeName, (char *)mddId, &name);
00280 
00281         /* Update the look-up tables in the graph */
00282         st_insert(PartPartitionReadNameToVertex(partition), 
00283                   name, (char *)fromVertex);
00284         st_insert(PartPartitionReadMddIdToVertex(partition),
00285                   (char *) mddId, (char *)fromVertex);
00286         
00287         /* Create vertex data */
00288         fromVertex->user_data = 
00289           (gGeneric)PartVertexInfoCreateSingle(name,
00290                                                Mvf_FunctionCreateFromVariable(manager, (int) mddId),
00291                                                (int) mddId);
00292       } 
00293       
00294       /* 
00295        * Add the edge to the graph. Make sure a self loop is not added. The
00296        * self loop may be produced by a mdd that has in its support the same
00297        * variables that represent the mddId of the node.
00298        */
00299       if (fromVertex != toVertex) {
00300         g_add_edge(fromVertex, toVertex);
00301       } /* End of if */
00302       
00303     } /* End of st_foreach_item */
00304     
00305     /* Clean the support table */
00306     st_free_table(mddSupport);
00307   } /* End of lsForEachItem */
00308   
00309   /* Clean up */
00310   st_free_table(mddIdToNodeName);
00311   st_free_table(tableOfLeaves);
00312   array_free(arrayOfRoots);
00313   lsDestroy(sinkList, (void (*)(lsGeneric))0);
00314   /* 
00315    * The contents of this array (array of mdds) is not deallocated because the
00316    * information has been transferred to the partition structure. All the
00317    * functions are stored now as part of the vertex information.
00318    */
00319   array_free(arrayOfMvf);
00320 
00321 } /* End of PartPartitionPartial */
00322 
00323 /*---------------------------------------------------------------------------*/
00324 /* Definition of static functions                                            */
00325 /*---------------------------------------------------------------------------*/