/**CFile*********************************************************************** FileName [partTotal.c] PackageName [part] Synopsis [Implements the partition of the network replicating exactly the network structure in the partition graph.] Description [Implements the partition that replicates the structure of the network. Every node in the network will be represented in the partition by a "single" vertex.] SeeAlso [part.h] Author [Abelardo Pardo] Copyright [This file was created at the University of Colorado at Boulder. The University of Colorado at Boulder makes no warranty about the suitability of this software for any purpose. It is presented on an AS IS basis.] ******************************************************************************/ #include "partInt.h" static char rcsid[] UNUSED = "$Id: partTotal.c,v 1.5 2005/04/16 06:14:54 fabio Exp $"; /*---------------------------------------------------------------------------*/ /* Constant declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Structure declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ /**AutomaticEnd***************************************************************/ /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Implements the partition that replicates the structure of the network.] Description [The procedure receives a pointer to a network, a pointer to a just created partition, and the lists of root and leave network nodes.
The procedure proceeds as follows. It creates the necessary data to call the function Ntm_NetworkBuildMdds. The array of roots and table of leaves are created in based to the parameters rootList<\tt> and leaveList<\tt> respectively. For each root node, its mvf is computed as a function of its inmediate fanin or the leaves, depending on the value of inTermsOfLeaves<\tt>. Once this computation has finished, one vertex per obtained function is added to the graph. Afterwards, for every vertex, the support of its multi-valued function is computed and the pertinent vertices created in the graph.] SideEffects [] SeeAlso [PartPartitionInputsOutputs] ******************************************************************************/ void PartPartitionTotal( Ntk_Network_t *network, graph_t *partition, lsList rootList, lsList leaveList, mdd_t *careSet, int inTermsOfLeaves) { Ntk_Node_t *nodePtr; /* Pointer to iterate over nodes */ lsList nodeList; /* list of network nodes */ lsGen gen; /* To iterate over lists */ array_t *setOfFunctions; array_t *rootArray; st_table *tableOfLeaves; vertex_t *toVertex; int i; /* Obtain the table of leaves of the partition */ tableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash); if (leaveList == (lsList)0) { Ntk_NetworkForEachCombInput(network, gen, nodePtr) { st_insert(tableOfLeaves, (char *)nodePtr, (char *) (long) (-1)); } } /* End of then */ else { lsForEachItem(leaveList, gen, nodePtr) { st_insert(tableOfLeaves, (char *) nodePtr, (char *) (long) (-1)); } } /* End of if-then-else */ /* Obtain the list of nodes to obtain the partition from */ if (rootList == (lsList)0) { nodeList = Ntk_NetworkReadNodes(network); } /* End of then */ else { array_t *temporaryRootArray; st_table *resultTable; st_generator *stgen; /* Translate the root list to an array */ temporaryRootArray = array_alloc(Ntk_Node_t *, lsLength(rootList)); i = 0; lsForEachItem(rootList, gen, nodePtr) { array_insert(Ntk_Node_t *, temporaryRootArray, i++, nodePtr); } /* Obtain the intermediate nodes */ resultTable = Ntk_RegionFindNodes(temporaryRootArray, tableOfLeaves); nodeList = lsCreate(); st_foreach_item(resultTable, stgen, (&nodePtr), NULL) { lsNewBegin(nodeList, (lsGeneric)nodePtr, NIL(lsHandle)); } /* Clean up */ st_free_table(resultTable); array_free(temporaryRootArray); } /* End of if-then-else */ rootArray = array_alloc(Ntk_Node_t *, 0); /* Make sure every network node has an mdd Id assigned to it */ lsForEachItem(nodeList, gen, nodePtr) { /* No need to assign mddIds to the shadow nodes */ if (Ntk_NodeTestIsShadow(nodePtr)) { continue; } /* End of if */ if (!inTermsOfLeaves || st_is_member(tableOfLeaves, (char *) nodePtr)) { if (Ntk_NodeReadMddId(nodePtr) == NTK_UNASSIGNED_MDD_ID) { Ord_NetworkAssignMddIdForNode(network, nodePtr); } /* End of if */ } /* End of if */ } /* End of lsForEachItem */ /* * If the result has to be in terms of the combinational inputs, the * mdd array for each vertex will be build all at once by * specifying all the nodes are roots and the combinational inputs * as leaves */ if (inTermsOfLeaves) { lsForEachItem(nodeList, gen, nodePtr) { /* Skip the shadow nodes */ if (Ntk_NodeTestIsShadow(nodePtr)) { continue; } /* Insert the node as root */ array_insert_last(Ntk_Node_t *, rootArray, nodePtr); } /* End of lsForEachItem */ setOfFunctions = Ntm_NetworkBuildMvfs(network, rootArray, tableOfLeaves, careSet); } /* End of then */ else { /* Compute every mdd array attached to the vertex in terms of its fanin */ array_t *parameterArray; st_table *tmptableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash); setOfFunctions = array_alloc(Mvf_Function_t *, 0); /* * This array will hold one node pointer as the parameter to build * the mdd array for a node. The array rootArray will be used to * create an array of node pointers. Therefore, at the end of this * if-then-else, setOfFunctions will hold the array of mdd arrays * and rootArray will hold the array with all the node pointers * whose mdd array was computed. */ parameterArray = array_alloc(Ntk_Node_t *, 1); lsForEachItem(nodeList, gen, nodePtr) { /* Skip the shadow nodes */ if (!Ntk_NodeTestIsShadow(nodePtr)) { Ntk_Node_t *faninPtr; /* Pointer to fanin node of current node */ array_t *temporaryArray; /* Create the array of nodes */ array_insert_last(Ntk_Node_t *, rootArray, nodePtr); /* This table is needed empty every beginning of iteration */ st_free_table(tmptableOfLeaves); tmptableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash); /* Prepare parameters to build the mdd array for the node */ array_insert(Ntk_Node_t *, parameterArray, 0, nodePtr); Ntk_NodeForEachFanin(nodePtr, i, faninPtr) { st_insert(tmptableOfLeaves, (char *)faninPtr, (char *)(-1)); } /* * If the node is a combinational inputs, it has no fanins but the node * must appear in the table of leaves, otherwise the function * Ntm_NetworkBuildMdds aborts. */ if (st_is_member(tableOfLeaves, (char *) nodePtr)) { st_insert(tmptableOfLeaves, (char *)nodePtr, (char *)(-1)); } /* End of if */ temporaryArray = Ntm_NetworkBuildMvfs(network, parameterArray, tmptableOfLeaves, careSet); array_insert_last(Mvf_Function_t *, setOfFunctions, array_fetch(Mvf_Function_t *, temporaryArray, 0)); array_free(temporaryArray); } /* End of if */ } /* End of lsForEachItem */ array_free(parameterArray); st_free_table(tmptableOfLeaves); } /* End of if-then-else */ /* Partial Clean up */ st_free_table(tableOfLeaves); assert(array_n(rootArray) == array_n(setOfFunctions)); /* * The computation now uses two steps, the first one creates all the * vertices of the partition and the second one all the edges of the * partition. */ /* Create vertices */ arrayForEachItem(Ntk_Node_t *, rootArray, i, nodePtr) { Mvf_Function_t *mvf = array_fetch(Mvf_Function_t *, setOfFunctions, i); char *name = Ntk_NodeReadName(nodePtr); int mddId = Ntk_NodeReadMddId(nodePtr); toVertex = g_add_vertex(partition); /* Update the look-up tables in the partition */ st_insert(PartPartitionReadNameToVertex(partition), name, (char *)toVertex); st_insert(PartPartitionReadMddIdToVertex(partition), (char *)(long) mddId, (char *)toVertex); /* Create the information attached to the vertex */ toVertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, mvf, mddId); } /* End of arrayForEachItem */ /* Create the edges */ foreach_vertex(partition, gen, toVertex) { nodePtr = Ntk_NetworkFindNodeByActualName(network, PartVertexReadName(toVertex)); if(!Ntk_NodeTestIsCombInput(nodePtr)) { PartPartitionCreateVertexFaninEdges(partition, toVertex); } } /* End of foreach_vertex */ /* Clean up */ array_free(rootArray); array_free(setOfFunctions); if (rootList != (lsList)0) { lsDestroy(nodeList, (void (*)(lsGeneric))0); } } /* End of PartPartitionTotal */ /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/