VIS
|
00001 00027 #include "partInt.h" 00028 00029 static char rcsid[] UNUSED = "$Id: partFine.c,v 1.5 2005/04/30 04:00:38 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 #define PartVertexReadGeneric(vPtr) ((PartVertexInfo_t *)(vPtr)->user_data)->generic 00056 #define PartVertexReadGeneric1(vPtr) ((PartVertexInfo_t *)(vPtr)->user_data)->generic1 00057 #define BASIC_PARTITION_UNIT 15 00058 00061 /*---------------------------------------------------------------------------*/ 00062 /* Static function prototypes */ 00063 /*---------------------------------------------------------------------------*/ 00064 00065 static int Part_IsFanoutInverter(Ntk_Node_t *node); 00066 00070 /*---------------------------------------------------------------------------*/ 00071 /* Definition of exported functions */ 00072 /*---------------------------------------------------------------------------*/ 00073 00074 00075 /*---------------------------------------------------------------------------*/ 00076 /* Definition of internal functions */ 00077 /*---------------------------------------------------------------------------*/ 00078 00079 00092 void 00093 PartPartitionFineGrain( 00094 Ntk_Network_t *network, 00095 graph_t *partition, 00096 mdd_t *careSet) 00097 { 00098 Ntk_Node_t *node; /* Pointer to iterate over nodes */ 00099 Mvf_Function_t *mddFunction; /* Pointer to a MDD */ 00100 mdd_manager *manager; /* Mdd manager in the partition */ 00101 st_table *tableOfLeaves; /* To store the leaves of the graph */ 00102 st_table *mddIdToNodeName; /* For quick lookup of node's name */ 00103 array_t *arrayOfMvf; /* To store the next state functions */ 00104 array_t *arrayOfRoots; /* To store the roots of the graph */ 00105 lsList sinkList; /* Vertices representing comb. outputs */ 00106 lsGen gen; /* To iterate over lists */ 00107 vertex_t *toVertex; /* Will hold the current function vertex */ 00108 int i; /* Index for loops */ 00109 long mddId; /* Will hold the mddId being processed */ 00110 st_table *mddSupport; /* To store the support of the Mvf_Function */ 00111 st_generator *stGen; /* To iterate over the MddIds of the support */ 00112 vertex_t *fromVertex; /* Will hold the current vertex in the support */ 00113 array_t *singletonMvfArray; 00114 array_t *singletonArrayOfRoots; 00115 array_t *tmpArrayOfMvf; 00116 Mvf_Function_t *nodeMvf; 00117 lsList sortedListOfNodes; 00118 array_t *sortedArrayOfPartitionNodes; 00119 array_t *unsortedArrayOfPartitionNodes; 00120 st_table *tableOfPartitionNodes; 00121 Ntk_Node_t *fanin, *fanout; 00122 00123 manager = PartPartitionReadMddManager(partition); 00124 00125 /* Make the combinational input nodes into leaves */ 00126 tableOfLeaves = st_init_table(st_ptrcmp, st_ptrhash); 00127 mddIdToNodeName = st_init_table(st_numcmp, st_numhash); 00128 Ntk_NetworkForEachCombInput(network, gen, node) { 00129 if(Ntk_NodeReadMddId(node) == NTK_UNASSIGNED_MDD_ID) 00130 Ord_NetworkAssignMddIdForNode(network, node); 00131 st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) ); 00132 st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 00133 Ntk_NodeReadName(node)); 00134 } 00135 00136 unsortedArrayOfPartitionNodes = array_alloc(Ntk_Node_t *, 0); 00137 tableOfPartitionNodes = st_init_table(st_ptrcmp, st_ptrhash); 00138 /* Make the target node list for partition */ 00139 Ntk_NetworkForEachNode(network, gen, node) { 00140 if(Ntk_NodeTestIsShadow(node)) continue; 00141 else if(Ntk_NodeTestIsCombInput(node)) continue; 00142 else if(Ntk_NodeTestIsCombOutput(node)) continue; 00143 else if(Ntk_NodeReadNumFanouts(node) == 1) { 00144 fanout = Part_GetFanoutFreeLogic(node); 00145 if(Ntk_NodeTestIsCombOutput(fanout)); 00146 else if(Ntk_NodeReadNumFanins(node) > 10); 00147 else if(Ntk_NodeReadNumFanins(fanout) == 1) continue; 00148 else if(!Part_CheckLeafNodeCondition(node, tableOfPartitionNodes, 5, 10)) { 00149 if(Ntk_NodeReadNumFanins(node) == 1) { 00150 fanin = Part_GetFaninFreeLogic(node); 00151 if(!fanin) continue; 00152 if(Ntk_NodeTestIsCombInput(fanin)) continue; 00153 } 00154 continue; 00155 } 00160 } 00169 array_insert_last(Ntk_Node_t *, unsortedArrayOfPartitionNodes, node); 00170 st_insert(tableOfPartitionNodes, (char *) node, (char *) (long) (-1)); 00171 } 00172 00173 /* create sorted array of partition nodes */ 00174 sortedListOfNodes = Ntk_NetworkComputeTopologicalOrder(network, 00175 unsortedArrayOfPartitionNodes, tableOfLeaves); 00176 00177 sortedArrayOfPartitionNodes = array_alloc(Ntk_Node_t *, 0); 00178 lsForEachItem(sortedListOfNodes, gen, node){ 00179 /* sortedListOfNodes includes many internal nodes, need to filter them out */ 00180 if(st_is_member(tableOfPartitionNodes, (char *) node)){ 00181 array_insert_last(Ntk_Node_t *, sortedArrayOfPartitionNodes, node); 00182 if(Ntk_NodeReadMddId(node) == NTK_UNASSIGNED_MDD_ID) 00183 Ord_NetworkAssignMddIdForNode(network, node); 00184 } 00185 } 00186 array_free(unsortedArrayOfPartitionNodes); 00187 lsDestroy(sortedListOfNodes, (void (*)(lsGeneric))0); 00188 st_free_table(tableOfPartitionNodes); 00189 00190 00191 tmpArrayOfMvf = array_alloc(Mvf_Function_t *, 0); 00192 for(i=0; i < array_n(sortedArrayOfPartitionNodes); i++){ 00193 node = array_fetch(Ntk_Node_t *, sortedArrayOfPartitionNodes, i); 00194 singletonArrayOfRoots = array_alloc(Ntk_Node_t *, 0); 00195 array_insert_last(Ntk_Node_t *, singletonArrayOfRoots, node); 00196 singletonMvfArray = Ntm_NetworkBuildMvfs(network, singletonArrayOfRoots, 00197 tableOfLeaves, careSet); 00198 nodeMvf = array_fetch(Mvf_Function_t *, singletonMvfArray, 0); 00199 array_insert_last(Mvf_Function_t *, tmpArrayOfMvf, nodeMvf); 00200 array_free(singletonMvfArray); 00201 array_free(singletonArrayOfRoots); 00202 00203 if(Ntk_NodeReadMddId(node) == NTK_UNASSIGNED_MDD_ID){ 00204 Ord_NetworkAssignMddIdForNode(network, node); 00205 } 00206 st_insert(tableOfLeaves, (char *)node, (char *) (long) (-1) ); 00207 st_insert(mddIdToNodeName, (char *) (long)Ntk_NodeReadMddId(node), 00208 Ntk_NodeReadName(node)); 00209 00210 } 00211 00212 00213 arrayOfRoots = array_alloc(Ntk_Node_t *, 0); 00214 Ntk_NetworkForEachCombOutput(network, gen, node) { 00215 array_insert_last(Ntk_Node_t *, arrayOfRoots, node); 00216 } 00217 arrayOfMvf = Ntm_NetworkBuildMvfs(network, arrayOfRoots, tableOfLeaves, 00218 careSet); 00219 00220 array_append(arrayOfRoots, sortedArrayOfPartitionNodes); 00221 array_append(arrayOfMvf, tmpArrayOfMvf); 00222 array_free(sortedArrayOfPartitionNodes); 00223 array_free(tmpArrayOfMvf); 00224 00225 00226 /* Create one vertex for every component of arrayOfMvf */ 00227 for (i=0; i < array_n(arrayOfRoots); i++) { 00228 node = array_fetch(Ntk_Node_t *, arrayOfRoots, i); 00229 mddId = Ntk_NodeReadMddId(node); 00230 00231 /* obtain the function attached to the node */ 00232 mddFunction = array_fetch(Mvf_Function_t *, arrayOfMvf, i); 00233 00234 00235 toVertex = g_add_vertex(partition); 00236 00237 /* Update the look-up tables in the graph */ 00238 st_insert(PartPartitionReadNameToVertex(partition), 00239 Ntk_NodeReadName(node), (char *)toVertex); 00240 if (mddId != -1) { 00241 st_insert(PartPartitionReadMddIdToVertex(partition), 00242 (char *)(long) mddId, (char *)toVertex); 00243 } 00244 toVertex->user_data = 00245 (gGeneric)PartVertexInfoCreateSingle(Ntk_NodeReadName(node), 00246 mddFunction, 00247 mddId); 00248 } 00249 00250 /* Read the list of vertices on the graph */ 00251 sinkList = lsCopy(g_get_vertices(partition), (lsGeneric (*)(lsGeneric))0); 00252 00253 /* 00254 * For every function on every combinational output, compute the 00255 * support and create vertices in the graph when needed 00256 */ 00257 lsForEachItem(sinkList, gen, toVertex) { 00258 mddFunction = PartVertexReadFunction(toVertex); 00259 mddSupport = PartCreateFunctionSupportTable(mddFunction); 00260 00261 /* 00262 * Create one edge (and one vertex if necessary) for every element 00263 * in mddSupport 00264 */ 00265 st_foreach_item(mddSupport, stGen, &mddId, NULL) { 00266 char *name; 00267 00268 /* Create vertex with the information if needed */ 00269 if (st_lookup(PartPartitionReadMddIdToVertex(partition), 00270 (char *)(long) mddId, &fromVertex) == 0) { 00271 fromVertex = g_add_vertex(partition); 00272 00273 st_lookup(mddIdToNodeName, (char *)(long) mddId, &name); 00274 00275 /* Update the look-up tables in the graph */ 00276 st_insert(PartPartitionReadNameToVertex(partition), 00277 name, (char *)fromVertex); 00278 st_insert(PartPartitionReadMddIdToVertex(partition), 00279 (char *)(long) mddId, (char *)fromVertex); 00280 00281 /* Create vertex data */ 00282 fromVertex->user_data = 00283 (gGeneric)PartVertexInfoCreateSingle(name, 00284 Mvf_FunctionCreateFromVariable(manager,mddId), 00285 mddId); 00286 } 00287 00288 /* 00289 * Add the edge to the graph. Make sure a self loop is not added. The 00290 * self loop may be produced by a mdd that has in its support the same 00291 * variables that represent the mddId of the node. 00292 */ 00293 if (fromVertex != toVertex) { 00294 g_add_edge(fromVertex, toVertex); 00295 } /* End of if */ 00296 00297 } /* End of st_foreach_item */ 00298 00299 /* Clean the support table */ 00300 st_free_table(mddSupport); 00301 } /* End of lsForEachItem */ 00302 00303 /* Clean up */ 00304 st_free_table(mddIdToNodeName); 00305 st_free_table(tableOfLeaves); 00306 array_free(arrayOfRoots); 00307 lsDestroy(sinkList, (void (*)(lsGeneric))0); 00308 /* 00309 * The contents of this array (array of mdds) is not deallocated because the 00310 * information has been transferred to the partition structure. All the 00311 * functions are stored now as part of the vertex information. 00312 */ 00313 array_free(arrayOfMvf); 00314 fprintf(stdout, "NOTICE : current peak memory = %ld\n", 00315 bdd_read_peak_memory(manager)); 00316 00317 } /* End of PartPartitionCut */ 00318 00319 00331 int 00332 Part_IsFanoutInverter(Ntk_Node_t *node) 00333 { 00334 Ntk_Node_t *fanout; 00335 00336 fanout = Part_GetFanoutFreeLogic(node); 00337 if(!fanout) return(1); 00338 if(Ntk_NodeReadNumFanins(fanout) == 1) return(1); 00339 else return(0); 00340 00341 } 00342 00354 int 00355 Part_CheckLeafNodeCondition(Ntk_Node_t *node, 00356 st_table *leafTable, 00357 int fanoutFreeLimit, 00358 int numVariableLimit) 00359 { 00360 int nVar, nDepth, i; 00361 Ntk_Node_t *fanout, *tnode, *tfanin; 00362 st_table *ownTable; 00363 00364 00365 nVar = Ntk_NodeReadNumFanins(node); 00366 nDepth = 0; 00367 fanout = node; 00368 ownTable = st_init_table(st_ptrcmp, st_ptrhash); 00369 while(1) { 00370 if(nDepth > fanoutFreeLimit)return(1); 00371 if(nVar > numVariableLimit) return(1); 00372 00373 if(!st_lookup(leafTable, fanout, &tnode)) { 00374 fanout = Part_GetFanoutFreeLogic(fanout); 00375 if(fanout == 0) break; 00376 if(Ntk_NodeTestIsCombInput(fanout)) break; 00377 if(Ntk_NodeTestIsCombOutput(fanout)) break; 00378 } 00379 else break; 00380 nDepth++; 00381 if(fanout == 0) break; 00382 nVar += Img_CutCalcTransitiveFanin(leafTable, ownTable, fanout, 00383 node, numVariableLimit); 00384 if(nVar > numVariableLimit) { 00385 st_free_table(ownTable); 00386 return(1); 00387 } 00388 } 00389 00390 Ntk_NodeForEachFanin(node, i, tfanin) { 00391 if(tfanin == 0) continue; 00392 if(Ntk_NodeReadNumFanouts(tfanin) != 1) continue; 00393 nVar += Img_CutCalcTransitiveFanin(leafTable, ownTable, tfanin, 0, numVariableLimit)-1; 00394 if(nVar > numVariableLimit) { 00395 st_free_table(ownTable); 00396 return(1); 00397 } 00398 } 00399 if(nVar > numVariableLimit) { 00400 st_free_table(ownTable); 00401 return(1); 00402 } 00429 return(0); 00430 } 00431 00443 int 00444 Img_CutCalcTransitiveFanin(st_table *table, 00445 st_table *ownTable, 00446 Ntk_Node_t *node, 00447 Ntk_Node_t *fanin, 00448 int limit) 00449 { 00450 int i, nVar; 00451 Ntk_Node_t *tfanin, *tnode; 00452 00453 nVar = 0; 00454 Ntk_NodeForEachFanin(node, i, tfanin) { 00455 if(tfanin == fanin) continue; 00456 if(tfanin == 0) continue; 00457 if(Ntk_NodeReadNumFanouts(tfanin) != 1){ 00458 if(!st_lookup(ownTable, tfanin, &tnode)) { 00459 st_insert(ownTable, tfanin, tfanin); 00460 nVar++; 00461 } 00462 continue; 00463 } 00464 if(Ntk_NodeTestIsCombInput(tfanin)) { 00465 if(!st_lookup(ownTable, tfanin, &tnode)) { 00466 st_insert(ownTable, tfanin, tfanin); 00467 nVar++; 00468 } 00469 continue; 00470 } 00471 if(Ntk_NodeTestIsCombOutput(tfanin)) { 00472 if(!st_lookup(ownTable, tfanin, &tnode)) { 00473 st_insert(ownTable, tfanin, tfanin); 00474 nVar++; 00475 } 00476 continue; 00477 } 00478 if(!st_lookup(table, tfanin, &tnode)) { 00479 nVar += Img_CutCalcTransitiveFanin(table, ownTable, tfanin, 0, limit); 00480 } 00481 else 00482 nVar++; 00483 if(nVar > limit) return(nVar); 00484 } 00485 return(nVar); 00486 } 00487 00499 Ntk_Node_t * 00500 Part_GetFaninFreeLogic(Ntk_Node_t *node) 00501 { 00502 int i; 00503 Ntk_Node_t *fanin; 00504 00505 Ntk_NodeForEachFanin(node, i, fanin) { 00506 if(Ntk_NodeReadNumFanouts(fanin) != 1) continue; 00507 return(fanin); 00508 } 00509 return(0); 00510 } 00511 00523 Ntk_Node_t * 00524 Part_GetFanoutFreeLogic(Ntk_Node_t *node) 00525 { 00526 int i; 00527 Ntk_Node_t *fanout; 00528 00529 if(Ntk_NodeReadNumFanouts(node) != 1) return(0); 00530 Ntk_NodeForEachFanout(node, i, fanout) { 00531 return(fanout); 00532 } 00533 return(0); 00534 }