VIS

src/part/partInOut.c

Go to the documentation of this file.
00001 
00033 #include "partInt.h"
00034 
00035 static char rcsid[] UNUSED = "$Id: partInOut.c,v 1.15 2005/04/16 14:52:45 fabio Exp $";
00036 
00039 /*---------------------------------------------------------------------------*/
00040 /* Static function prototypes                                                */
00041 /*---------------------------------------------------------------------------*/
00042 
00043 
00047 /*---------------------------------------------------------------------------*/
00048 /* Definition of exported functions                                          */
00049 /*---------------------------------------------------------------------------*/
00050 
00073 graph_t *
00074 Part_CreatePartitionFromMvfs(
00075   mdd_manager *manager,                      
00076   st_table *nameToMvf,
00077   st_table *nameToId,
00078   st_table *leafTable,
00079   char *partName)
00080 {
00081     graph_t        *partition;
00082     Mvf_Function_t *mddFunction;
00083     vertex_t       *toVertex;
00084     lsList         sinkList;
00085     lsGen          gen;
00086     st_table       *mddIdToNodeName;
00087     st_generator   *stGen;
00088     char           *str;
00089     long            mddId;
00090 
00091     /* Initialize variables */
00092     mddIdToNodeName = leafTable;
00093 
00094     /* Allocate the new partition to be returned */
00095     partition = g_alloc();
00096     if (partName) {
00097         partition->user_data = 
00098             (gGeneric)PartPartitionInfoCreate(partName,manager,Part_InOut_c);
00099     } /* End of if */
00100     else {
00101         partition->user_data = 
00102             (gGeneric)PartPartitionInfoCreate("dummy",manager,Part_InOut_c);
00103     } /* End of if-then-else */
00104 
00105     /* Create vertices for the functions in nameToMvf */
00106     st_foreach_item(nameToMvf,stGen,&str,&mddFunction) {
00107         toVertex = g_add_vertex(partition);
00108 
00109         /* Update the look-up tables in the graph */
00110         st_insert(PartPartitionReadNameToVertex(partition),str,toVertex);
00111         if (nameToId) {
00112             if (st_lookup(nameToId, str, &mddId)) {
00113                 st_insert(PartPartitionReadMddIdToVertex(partition),
00114                           (char *)mddId, toVertex);
00115             } /* End of if */
00116         } /* End of if */
00117 
00118         /* Fill in the fields of the data attached to the vertex */
00119         toVertex->user_data = 
00120             (gGeneric)PartVertexInfoCreateSingle(str, 
00121                                             Mvf_FunctionDuplicate(mddFunction),
00122                                             mddId);
00123     }
00124   
00125     /* Read the list of vertices on the graph */
00126     sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0);
00127 
00128     /* 
00129      * For every function on every combinational output, compute the
00130      * support and create vertices in the graph when needed 
00131      */
00132     lsForEachItem(sinkList, gen, toVertex) {
00133         st_table *mddSupport; /* Support of the Mvf_Function */
00134         st_generator *stGen;  /* To iterate over the MddIds of the support */
00135         vertex_t *fromVertex; /* Holds the current vertex in the support */
00136 
00137         /* Obtain an array of mdd_t * */
00138         mddFunction = PartVertexReadFunction(toVertex);
00139 
00140         /* Compute the support of the set of mdds*/
00141         mddSupport = PartCreateFunctionSupportTable(mddFunction);
00142 
00143         /* 
00144          * Create one edge (and one vertex if necessary) for every element
00145          * in mddSupport 
00146          */
00147         st_foreach_item(mddSupport, stGen, &mddId, NULL) {
00148             char *name;
00149 
00150             /* Create vertex with the information if needed */
00151             if (st_lookup(PartPartitionReadMddIdToVertex(partition), 
00152                           (char *)mddId, &fromVertex) == 0) {
00153                 fromVertex = g_add_vertex(partition);
00154         
00155                 st_lookup(mddIdToNodeName, (char *)mddId, &name);
00156 
00157                 /* Update the look-up tables in the graph */
00158                 st_insert(PartPartitionReadNameToVertex(partition), 
00159                           name, (char *)fromVertex);
00160                 st_insert(PartPartitionReadMddIdToVertex(partition),
00161                           (char *)(long) mddId, (char *)fromVertex);
00162         
00163                 /* Create vertex data */
00164                 fromVertex->user_data = 
00165                     (gGeneric)PartVertexInfoCreateSingle(name,
00166                               Mvf_FunctionCreateFromVariable(manager,mddId),
00167                                                          mddId);
00168             } /* End of if */
00169       
00170             /* 
00171              * Add the edge to the graph. Make sure a self loop is not added.
00172              * The self loop may be produced by a mdd that has in its support
00173              * the same variables that represent the mddId of the node.
00174              */
00175             if (fromVertex != toVertex) {
00176                 g_add_edge(fromVertex, toVertex);
00177             } /* End of if */
00178             
00179         } /* End of st_foreach_item */
00180     
00181         /* Clean the support table */
00182         st_free_table(mddSupport);
00183     } /* End of lsForEachItem */
00184 
00185     lsDestroy(sinkList, (void (*)(lsGeneric))0);
00186 
00187     return partition;
00188 } /* End of Part_CreatePartitionFromMvfs */
00189 
00211 graph_t *
00212 Part_NetworkCreatePartitionFromMvfs(
00213   Ntk_Network_t *network,
00214   st_table *nameToMvf)
00215 {
00216     graph_t        *partition;
00217     Ntk_Node_t     *node;
00218     Mvf_Function_t *mddFunction;
00219     vertex_t       *toVertex;
00220     mdd_manager    *manager;
00221     lsList         sinkList;
00222     lsGen          gen;
00223     st_table       *mddIdToNodeName;
00224     st_generator   *stGen;
00225     char           *ntkName;
00226     char           *str;
00227     long           mddId;
00228 
00229     /* Initialize variables */
00230     manager = Ntk_NetworkReadMddManager(network);
00231     ntkName = Ntk_NetworkReadName(network);
00232 
00233     /* Allocate the new partition to be returned */
00234     partition = g_alloc();
00235     partition->user_data = 
00236         (gGeneric)PartPartitionInfoCreate(ntkName,manager,Part_InOut_c);
00237 
00238     /* Create vertices for the functions in nameToMvf */
00239     st_foreach_item(nameToMvf,stGen,&str,&mddFunction) {
00240         node = Ntk_NetworkFindNodeByName(network,str);
00241         if (node == NIL(Ntk_Node_t)) {
00242             fprintf(vis_stderr,"%s has no corresponding node in network \n",
00243                     str);
00244             Part_PartitionFree(partition);
00245             return NIL(graph_t);
00246         }
00247         mddId = Ntk_NodeReadMddId(node);
00248         toVertex = g_add_vertex(partition);
00249 
00250         /* Update the look-up tables in the graph */
00251         st_insert(PartPartitionReadNameToVertex(partition),str,
00252                   (char *)toVertex);
00253 
00254         if (mddId != NTK_UNASSIGNED_MDD_ID) {
00255             st_insert(PartPartitionReadMddIdToVertex(partition),
00256                       (char *)(long) mddId, (char *)toVertex);
00257         }
00258 
00259         /* Fill in the fields of the data attached to the vertex */
00260         toVertex->user_data = 
00261             (gGeneric)PartVertexInfoCreateSingle(str, 
00262                                             Mvf_FunctionDuplicate(mddFunction),
00263                                             mddId);
00264     }
00265 
00266     /* Create a table for all the combinational inputs */
00267     mddIdToNodeName = st_init_table(st_numcmp, st_numhash);
00268     Ntk_NetworkForEachCombInput(network, gen, node) {
00269         st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 
00270                   Ntk_NodeReadName(node));
00271     }
00272   
00273     /* Read the list of vertices on the graph */
00274     sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0);
00275 
00276     /* 
00277      * For every function on every combinational output, compute the
00278      * support and create vertices in the graph when needed 
00279      */
00280     lsForEachItem(sinkList, gen, toVertex) {
00281         st_table *mddSupport; /* Support of the Mvf_Function */
00282         st_generator *stGen;  /* To iterate over the MddIds of the support */
00283         vertex_t *fromVertex; /* Holds the current vertex in the support */
00284 
00285         /* Obtain an array of mdd_t * */
00286         mddFunction = PartVertexReadFunction(toVertex);
00287 
00288         /* Compute the support of the set of mdds*/
00289         mddSupport = PartCreateFunctionSupportTable(mddFunction);
00290 
00291         /* 
00292          * Create one edge (and one vertex if necessary) for every element
00293          * in mddSupport 
00294          */
00295         st_foreach_item(mddSupport, stGen, &mddId, NULL) {
00296             char *name;
00297 
00298             /* Create vertex with the information if needed */
00299             if (st_lookup(PartPartitionReadMddIdToVertex(partition), 
00300                           (char *)mddId, &fromVertex) == 0) {
00301                 fromVertex = g_add_vertex(partition);
00302         
00303                 st_lookup(mddIdToNodeName, (char *)mddId, &name);
00304 
00305                 /* Update the look-up tables in the graph */
00306                 st_insert(PartPartitionReadNameToVertex(partition), 
00307                           name, (char *)fromVertex);
00308                 st_insert(PartPartitionReadMddIdToVertex(partition),
00309                           (char *)(long) mddId, (char *)fromVertex);
00310         
00311                 /* Create vertex data */
00312                 fromVertex->user_data = 
00313                     (gGeneric)PartVertexInfoCreateSingle(name,
00314                               Mvf_FunctionCreateFromVariable(manager,mddId),
00315                                                          mddId);
00316             } /* End of if */
00317       
00318             /* 
00319              * Add the edge to the graph. Make sure a self loop is not added.
00320              * The self loop may be produced by a mdd that has in its support
00321              * the same variables that represent the mddId of the node.
00322              */
00323             if (fromVertex != toVertex) {
00324                 g_add_edge(fromVertex, toVertex);
00325             } /* End of if */
00326             
00327         } /* End of st_foreach_item */
00328     
00329         /* Clean the support table */
00330         st_free_table(mddSupport);
00331     } /* End of lsForEachItem */
00332 
00333     st_free_table(mddIdToNodeName);
00334     lsDestroy(sinkList, (void (*)(lsGeneric))0);
00335 
00336     return partition;
00337 } /* End of Part_NetworkCreatePartitionFromMvfs */
00338 
00339 /*---------------------------------------------------------------------------*/
00340 /* Definition of internal functions                                          */
00341 /*---------------------------------------------------------------------------*/
00342 
00363 void
00364 PartPartitionInputsOutputs(
00365   Ntk_Network_t *network,
00366   graph_t *partition,
00367   lsList  rootList,
00368   lsList  leaveList,
00369   mdd_t   *careSet)
00370 {
00371   Ntk_Node_t     *node;            /* Pointer to iterate over nodes */
00372   Mvf_Function_t *mddFunction;     /* Pointer to a MDD */
00373   mdd_manager    *manager;         /* Mdd manager in the partition */
00374   st_table       *tableOfLeaves;   /* To store the leaves of the graph */
00375   st_table       *mddIdToNodeName; /* For quick lookup of node's name */
00376   array_t        *arrayOfMvf;      /* To store the next state functions */
00377   array_t        *arrayOfRoots;    /* To store the roots of the graph */
00378   lsList         sinkList;         /* Vertices representing comb. outputs */
00379   lsGen          gen;              /* To iterate over lists */
00380   vertex_t       *toVertex;        /* Will hold the current function vertex */
00381   int            i;                /* Index for loops */
00382   long            mddId;            /* Will hold the mddId being processed */
00383 
00384 
00385   manager = PartPartitionReadMddManager(partition);
00386 
00387   /* Take the nodes in leaveList as the leaves */
00388   tableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash);
00389   mddIdToNodeName = st_init_table(st_numcmp, st_numhash);
00390   if (leaveList == (lsList)0) {
00391     Ntk_NetworkForEachCombInput(network, gen, node) {
00392       st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) );
00393       st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 
00394                 Ntk_NodeReadName(node));
00395     }
00396   } /* End of then */ 
00397   else {
00398     lsForEachItem(leaveList, gen, node) {
00399       st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) );
00400       st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 
00401                 Ntk_NodeReadName(node));
00402     }
00403   } /* End of if-then-else */
00404 
00405   /* Take the nodes in rootList as the roots */
00406   if (rootList == (lsList)0) {
00407     arrayOfRoots = array_alloc(Ntk_Node_t *, 
00408                                Ntk_NetworkReadNumCombOutputs(network));
00409     i = 0;
00410     Ntk_NetworkForEachCombOutput(network, gen, node) {
00411       array_insert(Ntk_Node_t *, arrayOfRoots, i++, node);
00412     }
00413   } /* End of then */ 
00414   else {
00415     arrayOfRoots = array_alloc(Ntk_Node_t *, lsLength(rootList));
00416     i = 0;
00417     lsForEachItem(rootList, gen, node) {
00418       array_insert(Ntk_Node_t *, arrayOfRoots, i++, node);
00419     }
00420   } /* End of if-then-else */
00421 
00422   /* Build the next state functions as a function of the inputs */
00423   arrayOfMvf = Ntm_NetworkBuildMvfs(network, arrayOfRoots, tableOfLeaves, 
00424                                     careSet);
00425 
00426   /* Create one vertex for every component of arrayOfMvf */
00427   for (i=0; i < array_n(arrayOfRoots); i++) {
00428     node = array_fetch(Ntk_Node_t *, arrayOfRoots, i);
00429     
00430     mddId = Ntk_NodeReadMddId(node);
00431 
00432     /* obtain the function attached to the node */
00433     mddFunction = array_fetch(Mvf_Function_t *, arrayOfMvf, i);
00434     toVertex = g_add_vertex(partition);
00435     
00436     /* Update the look-up tables in the graph */
00437     st_insert(PartPartitionReadNameToVertex(partition),
00438               Ntk_NodeReadName(node), (char *)toVertex);
00439     if (mddId != NTK_UNASSIGNED_MDD_ID) {
00440       st_insert(PartPartitionReadMddIdToVertex(partition),
00441                 (char *)(long) mddId, (char *)toVertex);
00442     } /* End of if */
00443     toVertex->user_data = 
00444       (gGeneric)PartVertexInfoCreateSingle(Ntk_NodeReadName(node), 
00445                                            mddFunction, 
00446                                            mddId);
00447   } /* End of for */
00448   
00449   /* Read the list of vertices on the graph */
00450   sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0);
00451 
00452   /* 
00453    * For every function on every combinational output, compute the
00454    * support and create vertices in the graph when needed 
00455    */
00456   lsForEachItem(sinkList, gen, toVertex) {
00457     st_table     *mddSupport; /* To store the support of the Mvf_Function */
00458     st_generator *stGen;      /* To iterate over the MddIds of the support */
00459     vertex_t     *fromVertex; /* Will hold the current vertex in the support */
00460 
00461     /* Obtain an array of mdd_t * */
00462     mddFunction = PartVertexReadFunction(toVertex);
00463 
00464     /* Compute the support of the set of mdds*/
00465     mddSupport = PartCreateFunctionSupportTable(mddFunction);
00466 
00467     /* 
00468      * Create one edge (and one vertex if necessary) for every element
00469      * in mddSupport 
00470      */
00471     st_foreach_item(mddSupport, stGen, &mddId, NULL) {
00472       char *name;
00473 
00474       /* Create vertex with the information if needed */
00475       if (st_lookup(PartPartitionReadMddIdToVertex(partition), 
00476                     (char *)mddId, &fromVertex) == 0) {
00477         fromVertex = g_add_vertex(partition);
00478         
00479         st_lookup(mddIdToNodeName, (char *)mddId, &name);
00480 
00481         /* Update the look-up tables in the graph */
00482         st_insert(PartPartitionReadNameToVertex(partition), 
00483                   name, (char *)fromVertex);
00484         st_insert(PartPartitionReadMddIdToVertex(partition),
00485                   (char *)(long) mddId, (char *)fromVertex);
00486         
00487         /* Create vertex data */
00488         fromVertex->user_data = 
00489           (gGeneric)PartVertexInfoCreateSingle(name,
00490                                                Mvf_FunctionCreateFromVariable(manager,mddId),
00491                                                mddId);
00492       } /* End of if */
00493       
00494       /* 
00495        * Add the edge to the graph. Make sure a self loop is not added. The
00496        * self loop may be produced by a mdd that has in its support the same
00497        * variables that represent the mddId of the node.
00498        */
00499       if (fromVertex != toVertex) {
00500         g_add_edge(fromVertex, toVertex);
00501       } /* End of if */
00502       
00503     } /* End of st_foreach_item */
00504     
00505     /* Clean the support table */
00506     st_free_table(mddSupport);
00507   } /* End of lsForEachItem */
00508   
00509   /* Clean up */
00510   st_free_table(mddIdToNodeName);
00511   st_free_table(tableOfLeaves);
00512   array_free(arrayOfRoots);
00513   lsDestroy(sinkList, (void (*)(lsGeneric))0);
00514   /* 
00515    * The contents of this array (array of mdds) is not deallocated because the
00516    * information has been transferred to the partition structure. All the
00517    * functions are stored now as part of the vertex information.
00518    */
00519   array_free(arrayOfMvf);
00520   
00521 } /* End of PartPartitionInputsOutputs */
00522 
00523 
00544 int
00545 PartPartitionInOutChangeRoots(
00546   Ntk_Network_t *network,
00547   graph_t *partition,
00548   lsList  rootList,
00549   int verbosity)
00550 {
00551   Ntk_Node_t     *node;            /* Pointer to iterate over nodes */
00552   mdd_manager    *manager;         /* Mdd manager in the partition */
00553   lsList         newRootList;
00554   lsList         vertexList;
00555   lsGen          gen;              /* To iterate over lists */
00556   vertex_t       *vertex;
00557   char           *vertexName;
00558   long           initialTime, finalTime;
00559   st_table       *rootNodesTable = st_init_table(st_ptrcmp, st_ptrhash);
00560   mdd_t          *careSet;
00561 
00562   int prevNumOfLatchDataInput = 0;
00563   int prevNumOfPrimaryOutput = 0;
00564   int newNumOfLatchDataInput = 0;
00565   int newNumOfPrimaryOutput = 0;
00566   int overlapNumOfLatchDataInput = 0;
00567   int overlapNumOfPrimaryOutPut = 0;
00568 
00569   initialTime = util_cpu_time();
00570 
00571   manager = PartPartitionReadMddManager(partition);
00572   vertexList = g_get_vertices(partition);
00573 
00574   lsForEachItem(vertexList, gen, vertex){
00575     vertexName = PartVertexReadName(vertex);
00576     node = Ntk_NetworkFindNodeByName(network, vertexName);
00577     if (Ntk_NodeTestIsCombOutput(node)){
00578       st_insert(rootNodesTable, (char *)node, (char *)(long)(-1));
00579       if (Ntk_NodeTestIsLatchDataInput(node)){
00580         prevNumOfLatchDataInput++;
00581       }else if (Ntk_NodeTestIsPrimaryOutput(node)){
00582         prevNumOfPrimaryOutput++;
00583       }
00584     }
00585   }
00586 
00587   newRootList = lsCreate();
00588   lsForEachItem(rootList, gen, node){
00589     if (!(st_is_member(rootNodesTable, (char *)node))){
00590       lsNewEnd(newRootList, (lsGeneric)node, LS_NH);
00591       if (Ntk_NodeTestIsLatchDataInput(node)){
00592         newNumOfLatchDataInput++;
00593       }else if (Ntk_NodeTestIsPrimaryOutput(node)){
00594         newNumOfPrimaryOutput++;
00595       }
00596     }else{
00597       if (Ntk_NodeTestIsLatchDataInput(node)){
00598         overlapNumOfLatchDataInput++;
00599       }else if (Ntk_NodeTestIsPrimaryOutput(node)){
00600         overlapNumOfPrimaryOutPut++;
00601       }
00602     }
00603   }
00604 
00605   st_free_table(rootNodesTable);
00606 
00607   if (lsLength(newRootList) > 0){
00608     careSet = mdd_one(manager);
00609     PartPartitionInputsOutputs(network, partition, newRootList, 
00610                                (lsList)0, careSet);
00611     mdd_free(careSet);
00612   }
00613 
00614   lsDestroy(newRootList, (void (*)(lsGeneric))0);
00615 
00616   finalTime = util_cpu_time();
00617 
00618   if (verbosity >= 2){
00619     fprintf(vis_stdout, "PART: Partition is changed.\n");
00620     fprintf(vis_stdout, "PART: Old - %d next state functions\n",
00621             prevNumOfLatchDataInput);
00622     fprintf(vis_stdout, "PART: Old - %d primary outputs\n",
00623             prevNumOfPrimaryOutput);
00624     fprintf(vis_stdout, "PART: New - %d next state functions\n",
00625             prevNumOfLatchDataInput + newNumOfLatchDataInput);
00626     fprintf(vis_stdout, "PART: New - %d primary outputs\n",
00627             prevNumOfPrimaryOutput + newNumOfPrimaryOutput);
00628     fprintf(vis_stdout, "PART: Partitioning time = %10ld\n",
00629                     (finalTime - initialTime) / 1000);
00630     Part_PartitionPrintStats(vis_stdout, partition, FALSE);
00631   }
00632 
00633   /*
00634    * Is partition increased?
00635    */
00636   if (newNumOfLatchDataInput + newNumOfPrimaryOutput > 0){
00637     return 1;
00638   }else{
00639     return 0;
00640   } 
00641 } /* End of PartPartitionInOutChangeRoots */
00642 
00643 /*---------------------------------------------------------------------------*/
00644 /* Definition of static functions                                            */
00645 /*---------------------------------------------------------------------------*/
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656