VIS
|
00001 00041 #include "partInt.h" 00042 00043 static char rcsid[] UNUSED = "$Id: partFrontier.c,v 1.25 2005/05/11 20:50:32 jinh Exp $"; 00044 00045 /*---------------------------------------------------------------------------*/ 00046 /* Constant declarations */ 00047 /*---------------------------------------------------------------------------*/ 00048 00049 00050 /*---------------------------------------------------------------------------*/ 00051 /* Stucture declarations */ 00052 /*---------------------------------------------------------------------------*/ 00053 00054 /*---------------------------------------------------------------------------*/ 00055 /* Type declarations */ 00056 /*---------------------------------------------------------------------------*/ 00057 00058 00059 /*---------------------------------------------------------------------------*/ 00060 /* Variable declarations */ 00061 /*---------------------------------------------------------------------------*/ 00062 00063 /*---------------------------------------------------------------------------*/ 00064 /* Macro declarations */ 00065 /*---------------------------------------------------------------------------*/ 00066 00067 00070 /*---------------------------------------------------------------------------*/ 00071 /* Static function prototypes */ 00072 /*---------------------------------------------------------------------------*/ 00073 00074 static void PartitionCreateEdges(graph_t *partition); 00075 static Mvf_Function_t * NodeBuildMvf(Ntk_Node_t * node, st_table * nodeToMvfTable); 00076 static Mvf_Function_t * NodeBuildMvf2(Ntk_Node_t * node, st_table * nodeToMvfTable, st_table *faninNumberTable); 00077 static Mvf_Function_t * NodeBuildPseudoInputMvf(Ntk_Node_t * node); 00078 static void PrintPartitionRecursively(vertex_t *vertex, st_table *vertexTable, int indent); 00079 00083 /*---------------------------------------------------------------------------*/ 00084 /* Definition of exported functions */ 00085 /*---------------------------------------------------------------------------*/ 00086 00100 void 00101 Part_PartitionReadOrCreateBnvs( 00102 Ntk_Network_t *network, 00103 st_table *coiLatchTable, 00104 st_table *coiBnvTable) 00105 { 00106 graph_t *partition; 00107 lsGen lsgen; 00108 vertex_t *vertex; 00109 long mddId; 00110 Ntk_Node_t *node; 00111 00112 /* if the partition is not available, sweep the network */ 00113 partition = Part_NetworkReadPartition(network); 00114 if (partition == NIL(graph_t)) { 00115 PartInsertBnvs(network, coiLatchTable, coiBnvTable); 00116 return; 00117 } 00118 00119 /* otherwise, go through the vertices */ 00120 foreach_vertex(partition, lsgen, vertex) { 00121 mddId = PartVertexReadMddId(vertex); 00122 if (mddId == -1) continue; 00123 00124 node = Ntk_NetworkFindNodeByMddId(network, mddId); 00125 assert(node != NIL(Ntk_Node_t)); 00126 00127 if ( !Ntk_NodeTestIsCombInput(node) && 00128 Ntk_NodeReadNumFanouts(node)!=0 ) 00129 st_insert(coiBnvTable, (char *)node, NIL(char)); 00130 } 00131 00132 } 00133 00147 void 00148 Part_PartitionWithExistingBnvs( 00149 Ntk_Network_t *network, 00150 graph_t *partition, 00151 st_table *coiBnvTable, 00152 st_table *absLatchTable, 00153 st_table *absBnvTable) 00154 { 00155 00156 PartPartitionWithExistingBnvs(network, partition, coiBnvTable, 00157 absLatchTable, absBnvTable); 00158 } 00159 00160 /*---------------------------------------------------------------------------*/ 00161 /* Definition of internal functions */ 00162 /*---------------------------------------------------------------------------*/ 00163 00199 void 00200 PartPartitionFrontier(Ntk_Network_t *network, 00201 graph_t *partition, 00202 lsList rootList, 00203 lsList leaveList, 00204 mdd_t *careSet) 00205 { 00206 Ntk_Node_t *node; /* Pointer to iterate over nodes */ 00207 lsGen gen; /* To iterate over lists */ 00208 vertex_t *vertex; /* Destination of the edge being added */ 00209 char *name; /* Name of the node being processed */ 00210 int mddId; /* Id of the node being processed */ 00211 int i; 00212 mdd_manager *mddManager = PartPartitionReadMddManager(partition); 00213 /* nodeToMvfTable maps a node to the mvf in the form that is needed to build 00214 mvfs for the fanouts of the node. I.e., a cutpoint node is mapped to an 00215 mdd for a new variable. */ 00216 st_table *nodeToMvfTable = st_init_table(st_ptrcmp, st_ptrhash); 00217 st_table *leafNodesTable = st_init_table(st_ptrcmp, st_ptrhash); 00218 st_table *topoNodeTable; 00219 Ntk_Node_t *fanoutNode; 00220 array_t *rootNodesArray; 00221 long fanoutNumber = 0; 00222 Mvf_Function_t *nodeMvf; 00223 long bddSize; 00224 int sizeThreshold; 00225 lsList topologicalNodeList; 00226 lsGen lsgen; 00227 st_generator *stgen; 00228 char *flagValue = Cmd_FlagReadByName("partition_threshold"); 00229 00230 if (flagValue == NIL(char)){ 00231 sizeThreshold = 1000; /* the default value */ 00232 } 00233 else { 00234 sizeThreshold = atoi(flagValue); 00235 } 00236 00237 /* Put combinational inputs in the leafNodesTable. */ 00238 if (leaveList == (lsList)0) { 00239 Ntk_NetworkForEachCombInput(network, gen, node) { 00240 st_insert(leafNodesTable, (char *)node, (char *) (long) (-1) ); 00241 } 00242 } /* End of then */ 00243 else { 00244 lsForEachItem(leaveList, gen, node) { 00245 st_insert(leafNodesTable, (char *)node, (char *) (long) (-1) ); 00246 } 00247 } /* End of if-then-else */ 00248 00249 00250 /* Take the nodes in rootList as the roots */ 00251 if (rootList == (lsList)0) { 00252 rootNodesArray = array_alloc(Ntk_Node_t *, 00253 Ntk_NetworkReadNumCombOutputs(network)); 00254 i = 0; 00255 Ntk_NetworkForEachCombOutput(network, gen, node) { 00256 array_insert(Ntk_Node_t *, rootNodesArray, i++, node); 00257 } 00258 00259 } /* End of then */ 00260 else { 00261 rootNodesArray = array_alloc(Ntk_Node_t *, lsLength(rootList)); 00262 i = 0; 00263 lsForEachItem(rootList, gen, node) { 00264 array_insert(Ntk_Node_t *, rootNodesArray, i++, node); 00265 } 00266 } /* End of if-then-else */ 00267 00268 /* Get an array of nodes sorted in topological order */ 00269 topologicalNodeList = Ntk_NetworkComputeTopologicalOrder(network, 00270 rootNodesArray, 00271 leafNodesTable); 00272 00273 /* For each node, compute the number of its fanouts */ 00274 topoNodeTable = st_init_table(st_ptrcmp, st_ptrhash); 00275 lsForEachItem(topologicalNodeList, lsgen, node){ 00276 st_insert(topoNodeTable, (char *)node, NIL(char)); 00277 } 00278 lsForEachItem(topologicalNodeList, lsgen, node){ 00279 fanoutNumber = 0; 00280 Ntk_NodeForEachFanout(node, i, fanoutNode) { 00281 if (st_is_member(topoNodeTable, fanoutNode) && 00282 !st_is_member(leafNodesTable, fanoutNode)) 00283 fanoutNumber++; 00284 } 00285 st_insert(topoNodeTable, node, (char *) fanoutNumber); 00286 } 00287 00288 /* For each leaf nodes, create a vertex in the partition, create the mvf, and 00289 * a mapping of name to vertex, and mddId to vertex. 00290 */ 00291 st_foreach_item(leafNodesTable, stgen, &node, NULL) { 00292 if (!st_lookup(topoNodeTable, node, &fanoutNumber)) { 00293 continue; 00294 } 00295 mddId = Ntk_NodeReadMddId(node); 00296 assert(mddId != NTK_UNASSIGNED_MDD_ID); 00297 vertex = g_add_vertex(partition); 00298 name = Ntk_NodeReadName(node); 00299 st_insert(PartPartitionReadNameToVertex(partition), name, vertex); 00300 st_insert(PartPartitionReadMddIdToVertex(partition), (char *)(long)mddId, 00301 vertex); 00302 00303 if (Ntk_NodeTestIsPseudoInput(node)){ 00304 nodeMvf = NodeBuildPseudoInputMvf(node); 00305 } 00306 else { 00307 nodeMvf = Mvf_FunctionCreateFromVariable(mddManager,mddId); 00308 } 00309 00310 if (fanoutNumber <= 0) { 00311 st_insert(nodeToMvfTable, (char *)node, NIL(char)); 00312 }else 00313 st_insert(nodeToMvfTable, (char *)node, 00314 (char *)Mvf_FunctionDuplicate(nodeMvf)); 00315 00316 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, nodeMvf, 00317 mddId); 00318 } 00319 00320 st_free_table(leafNodesTable); 00321 00322 00323 fflush(vis_stdout); 00324 00325 /* Go through the topologicalNodeList 00326 * a. If the node is of combinational input type, continue. 00327 * 00328 * b. Otherwise, Build the Mdd for this node, in terms of the function of the 00329 * fanin nodes in. If the Mdd size exceeds the threshold, create an Mdd ID 00330 * for this node. 00331 */ 00332 00333 lsForEachItem(topologicalNodeList, lsgen, node){ 00334 if (st_is_member(nodeToMvfTable, (char *)node)) continue; 00335 00336 nodeMvf = NodeBuildMvf2(node, nodeToMvfTable, topoNodeTable); 00337 bddSize = bdd_size_multiple(nodeMvf); 00338 00339 if ((bddSize <= sizeThreshold) && !Ntk_NodeTestIsCombOutput(node)) { 00340 st_insert(nodeToMvfTable, node, nodeMvf); 00341 continue; 00342 } 00343 00344 /* node either is a primary output, or has an mvf exceeding the 00345 * threshold. 00346 */ 00347 st_lookup(topoNodeTable, node, &fanoutNumber); 00348 if ( (bddSize > sizeThreshold) && fanoutNumber > 0 ) { 00349 if ((mddId = Ntk_NodeReadMddId(node)) == -1){ 00350 Ord_NetworkAssignMddIdForNode(network, node); 00351 mddId = Ntk_NodeReadMddId(node); 00352 } 00353 st_insert(nodeToMvfTable, node, 00354 Mvf_FunctionCreateFromVariable(mddManager,mddId)); 00355 }else { 00356 if (fanoutNumber <= 0) { 00357 st_insert(nodeToMvfTable, node, NIL(char)); 00358 }else 00359 st_insert(nodeToMvfTable, (char *)node, 00360 (char *)Mvf_FunctionDuplicate(nodeMvf)); 00361 } 00362 00363 vertex = g_add_vertex(partition); 00364 name = Ntk_NodeReadName(node); 00365 mddId = Ntk_NodeReadMddId(node); 00366 st_insert(PartPartitionReadNameToVertex(partition), name, (char *)vertex); 00367 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, nodeMvf, 00368 mddId); 00369 if (mddId != -1){ 00370 st_insert(PartPartitionReadMddIdToVertex(partition), 00371 (char *)(long)mddId, (char *)vertex); 00372 } 00373 }/* for each member of topologicalNodeList */ 00374 00375 00376 /* sanity check */ 00377 st_foreach_item(nodeToMvfTable, stgen, &node, &nodeMvf) { 00378 #if 0 00379 if (nodeMvf != NIL(Mvf_Function_t)) { 00380 int chk = st_lookup(topoNodeTable, node, &fanoutNumber); 00381 Ntk_NodeForEachFanout(node, i, fanoutNode) { 00382 fprintf(vis_stdout, "\nunclean node %s => %s", 00383 Ntk_NodeReadName(node), 00384 Ntk_NodeReadName(fanoutNode)); 00385 if (Ntk_NodeTestIsLatch(fanoutNode)) 00386 fprintf(vis_stdout, "\t(latch)"); 00387 } 00388 } 00389 #else 00390 assert (nodeMvf == NIL(Mvf_Function_t)) ; 00391 #endif 00392 } 00393 00394 PartitionCreateEdges(partition); 00395 array_free(rootNodesArray); 00396 st_free_table(nodeToMvfTable); 00397 st_free_table(topoNodeTable); 00398 lsDestroy(topologicalNodeList, (void (*)(lsGeneric))0); 00399 } 00400 00401 #if 0 00402 void 00403 PartPartitionFrontierOld(Ntk_Network_t *network, 00404 graph_t *partition, 00405 lsList rootList, 00406 lsList leaveList, 00407 mdd_t *careSet) 00408 { 00409 Ntk_Node_t *node; /* Pointer to iterate over nodes */ 00410 lsGen gen; /* To iterate over lists */ 00411 vertex_t *vertex; /* Destination of the edge being added */ 00412 char *name; /* Name of the node being processed */ 00413 int mddId; /* Id of the node being processed */ 00414 int i; 00415 mdd_manager *mddManager = PartPartitionReadMddManager(partition); 00416 /* nodeToMvfTable maps a node to the mvf in the form that is needed to build 00417 mvfs for the fanouts of the node. I.e., a cutpoint node is mapped to an 00418 mdd for a new variable. */ 00419 st_table *nodeToMvfTable = st_init_table(st_ptrcmp, st_ptrhash); 00420 st_table *leafNodesTable = st_init_table(st_ptrcmp, st_ptrhash); 00421 array_t *rootNodesArray; 00422 Mvf_Function_t *nodeMvf; 00423 long bddSize; 00424 int sizeThreshold; 00425 lsList topologicalNodeList; 00426 lsGen lsgen; 00427 st_generator *stgen; 00428 char *flagValue = Cmd_FlagReadByName("partition_threshold"); 00429 if (flagValue == NIL(char)){ 00430 sizeThreshold = 1000; /* the default value */ 00431 } 00432 else { 00433 sizeThreshold = atoi(flagValue); 00434 } 00435 00436 /* Put combinational inputs in the leafNodesTable. */ 00437 if (leaveList == (lsList)0) { 00438 Ntk_NetworkForEachCombInput(network, gen, node) { 00439 st_insert(leafNodesTable, (char *)node, (char *) (long) (-1) ); 00440 } 00441 } /* End of then */ 00442 else { 00443 lsForEachItem(leaveList, gen, node) { 00444 st_insert(leafNodesTable, (char *)node, (char *) (long) (-1) ); 00445 } 00446 } /* End of if-then-else */ 00447 00448 /* 00449 * For each leaf nodes, create a vertex in the partition, create the mvf, and 00450 * a mapping of name to vertex, and mddId to vertex. 00451 */ 00452 st_foreach_item(leafNodesTable, stgen, &node, NULL){ 00453 mddId = Ntk_NodeReadMddId(node); 00454 assert(mddId != NTK_UNASSIGNED_MDD_ID); 00455 vertex = g_add_vertex(partition); 00456 name = Ntk_NodeReadName(node); 00457 st_insert(PartPartitionReadNameToVertex(partition), name, (char *)vertex); 00458 st_insert(PartPartitionReadMddIdToVertex(partition), (char *)(long)mddId, 00459 (char *)vertex); 00460 if (Ntk_NodeTestIsPseudoInput(node)){ 00461 nodeMvf = NodeBuildPseudoInputMvf(node); 00462 } 00463 else { 00464 nodeMvf = Mvf_FunctionCreateFromVariable(mddManager,mddId); 00465 } 00466 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 00467 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, nodeMvf, 00468 mddId); 00469 } 00470 00471 00472 /* Take the nodes in rootList as the roots */ 00473 if (rootList == (lsList)0) { 00474 rootNodesArray = array_alloc(Ntk_Node_t *, 00475 Ntk_NetworkReadNumCombOutputs(network)); 00476 i = 0; 00477 Ntk_NetworkForEachCombOutput(network, gen, node) { 00478 array_insert(Ntk_Node_t *, rootNodesArray, i++, node); 00479 } 00480 } /* End of then */ 00481 else { 00482 rootNodesArray = array_alloc(Ntk_Node_t *, lsLength(rootList)); 00483 i = 0; 00484 lsForEachItem(rootList, gen, node) { 00485 array_insert(Ntk_Node_t *, rootNodesArray, i++, node); 00486 } 00487 } /* End of if-then-else */ 00488 00489 00490 00491 /* Get an array of nodes sorted in topological order */ 00492 topologicalNodeList = Ntk_NetworkComputeTopologicalOrder(network, 00493 rootNodesArray, 00494 leafNodesTable); 00495 00496 st_free_table(leafNodesTable); 00497 00498 00499 /* Go through the topologicalNodeList 00500 * a. If the node is of combinational input type, continue. 00501 * 00502 * b. Otherwise, Build the Mdd for this node, in terms of the function of the 00503 * fanin nodes in. If the Mdd size exceeds the threshold, create an Mdd ID 00504 * for this node. 00505 */ 00506 00507 lsForEachItem(topologicalNodeList, lsgen, node){ 00508 if (st_is_member(nodeToMvfTable, (char *)node)) continue; 00509 nodeMvf = NodeBuildMvf(node, nodeToMvfTable); 00510 bddSize = bdd_size_multiple(nodeMvf); 00511 if ((bddSize <= sizeThreshold) && 00512 (Ntk_NodeTestIsCombOutput(node) == 0)){ 00513 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 00514 continue; 00515 } 00516 /* node either is a primary output, or has an mvf exceeding the 00517 threshold. */ 00518 vertex = g_add_vertex(partition); 00519 name = Ntk_NodeReadName(node); 00520 st_insert(PartPartitionReadNameToVertex(partition), name, 00521 (char *)vertex); 00522 if ((bddSize > sizeThreshold) && 00523 (Ntk_NodeReadNumFanouts(node) != 0)){ 00524 if ((mddId = Ntk_NodeReadMddId(node)) == -1){ 00525 Ord_NetworkAssignMddIdForNode(network, node); 00526 mddId = Ntk_NodeReadMddId(node); 00527 } 00528 st_insert(nodeToMvfTable, (char *)node, 00529 (char *)Mvf_FunctionCreateFromVariable(mddManager,mddId)); 00530 } 00531 else { 00532 /* Small mvf, or no fanout */ 00533 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 00534 } 00535 mddId = Ntk_NodeReadMddId(node); 00536 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, 00537 nodeMvf, 00538 mddId); 00539 if (mddId != -1){ 00540 st_insert(PartPartitionReadMddIdToVertex(partition), 00541 (char *)(long)mddId, (char *)vertex); 00542 } 00543 }/* for each member of topologicalNodeList */ 00544 00545 /* 00546 * Free the Mvfs in nodeToMvfTable not associated with vertices in the 00547 * partition. The mvfs of inputs are always in the partition; hence, 00548 * their mvfs should always be preserved. For outputs, we have to free 00549 * the mvf in nodeToMvfTable if the output is also a cutpoint, because in 00550 * this case the mvf in the partition vertex and the one in the 00551 * nodeToMvfTable are different. 00552 */ 00553 00554 lsForEachItem(topologicalNodeList, gen, node){ 00555 if (!Ntk_NodeTestIsCombInput(node)){ 00556 if(!Ntk_NodeTestIsCombOutput(node)){ 00557 st_lookup(nodeToMvfTable, node, &nodeMvf); 00558 assert(nodeMvf != NIL(Mvf_Function_t)); 00559 Mvf_FunctionFree(nodeMvf); 00560 } else { 00561 Mvf_Function_t *vertexMvf; 00562 00563 name = Ntk_NodeReadName(node); 00564 vertex = Part_PartitionFindVertexByName(partition, name); 00565 st_lookup(nodeToMvfTable, node, &nodeMvf); 00566 vertexMvf = PartVertexReadFunction(vertex); 00567 assert(nodeMvf != NIL(Mvf_Function_t) && 00568 vertexMvf != NIL(Mvf_Function_t)); 00569 if(vertexMvf != nodeMvf){ 00570 Mvf_FunctionFree(nodeMvf); 00571 } 00572 } 00573 }/* not input */ 00574 }/* for each node */ 00575 00576 PartitionCreateEdges(partition); 00577 array_free(rootNodesArray); 00578 st_free_table(nodeToMvfTable); 00579 lsDestroy(topologicalNodeList, (void (*)(lsGeneric))0); 00580 } 00581 #endif 00582 00598 void 00599 PartUpdateFrontier(Ntk_Network_t *network, 00600 graph_t *partition, 00601 lsList rootList, 00602 lsList leaveList, 00603 mdd_t *careSet) 00604 { 00605 Ntk_Node_t *node; /* Pointer to iterate over nodes */ 00606 lsGen gen; /* To iterate over lists */ 00607 vertex_t *vertex; /* Destination of the edge being added */ 00608 char *name; /* Name of the node being processed */ 00609 int mddId; /* Id of the node being processed */ 00610 int i, flag; 00611 mdd_manager *mddManager = PartPartitionReadMddManager(partition); 00612 /* nodeToMvfTable maps a node to the mvf in the form that is needed to build 00613 mvfs for the fanouts of the node. I.e., a cutpoint node is mapped to an 00614 mdd for a new variable. */ 00615 st_table *nodeToMvfTable = st_init_table(st_ptrcmp, st_ptrhash); 00616 st_table *leafNodesTable = st_init_table(st_ptrcmp, st_ptrhash); 00617 array_t *rootNodesArray; 00618 Mvf_Function_t *nodeMvf; 00619 long bddSize; 00620 int sizeThreshold; 00621 lsList topologicalNodeList; 00622 lsGen lsgen; 00623 st_generator *stgen; 00624 char *flagValue = Cmd_FlagReadByName("partition_threshold"); 00625 00626 if (flagValue == NIL(char)){ 00627 sizeThreshold = 1000; /* the default value */ 00628 } 00629 else { 00630 sizeThreshold = atoi(flagValue); 00631 } 00632 00633 /* Put combinational inputs in the leafNodesTable. */ 00634 if (leaveList == (lsList)0) { 00635 Ntk_NetworkForEachCombInput(network, gen, node) { 00636 st_insert(leafNodesTable, (char *)node, (char *) (long) (-1) ); 00637 } 00638 } /* End of then */ 00639 else { 00640 lsForEachItem(leaveList, gen, node) { 00641 st_insert(leafNodesTable, (char *)node, (char *) (long) (-1) ); 00642 } 00643 } /* End of if-then-else */ 00644 00645 /* 00646 * For each leaf nodes, create a vertex in the partition, create the mvf, and 00647 * a mapping of name to vertex, and mddId to vertex. 00648 * Notices that: if a vertex exists in the partition, use it instead of 00649 * creating a new one. 00650 */ 00651 st_foreach_item(leafNodesTable, stgen, &node, NULL){ 00652 mddId = Ntk_NodeReadMddId(node); 00653 name = Ntk_NodeReadName(node); 00654 assert(mddId != NTK_UNASSIGNED_MDD_ID); 00655 flag = st_lookup(PartPartitionReadNameToVertex(partition), 00656 name, &vertex); 00657 if (flag) { 00658 nodeMvf = ((PartVertexInfo_t *)(vertex->user_data))->functionality.mvf; 00659 st_insert(nodeToMvfTable, node, nodeMvf); 00660 /* 00661 name = Ntk_NodeReadName(node); 00662 fprintf(vis_stdout, "warning: node %s already in the partition\n", 00663 name); 00664 */ 00665 }else { 00666 vertex = g_add_vertex(partition); 00667 st_insert(PartPartitionReadNameToVertex(partition), name, (char *)vertex); 00668 st_insert(PartPartitionReadMddIdToVertex(partition), (char *)(long)mddId, 00669 (char *)vertex); 00670 if (Ntk_NodeTestIsPseudoInput(node)){ 00671 nodeMvf = NodeBuildPseudoInputMvf(node); 00672 }else { 00673 nodeMvf = Mvf_FunctionCreateFromVariable(mddManager,mddId); 00674 } 00675 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 00676 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, nodeMvf, 00677 mddId); 00678 } 00679 } 00680 00681 /* Take the nodes in rootList as the roots */ 00682 if (rootList == (lsList)0) { 00683 rootNodesArray = array_alloc(Ntk_Node_t *, 00684 Ntk_NetworkReadNumCombOutputs(network)); 00685 i = 0; 00686 Ntk_NetworkForEachCombOutput(network, gen, node) { 00687 name = Ntk_NodeReadName(node); 00688 if ( !st_is_member(PartPartitionReadNameToVertex(partition), name) ) 00689 array_insert(Ntk_Node_t *, rootNodesArray, i++, node); 00690 } 00691 } /* End of then */ 00692 else { 00693 rootNodesArray = array_alloc(Ntk_Node_t *, lsLength(rootList)); 00694 i = 0; 00695 lsForEachItem(rootList, gen, node) { 00696 name = Ntk_NodeReadName(node); 00697 if ( !st_is_member(PartPartitionReadNameToVertex(partition), name) ) 00698 array_insert(Ntk_Node_t *, rootNodesArray, i++, node); 00699 } 00700 } /* End of if-then-else */ 00701 00702 00703 00704 /* Get an array of nodes sorted in topological order */ 00705 topologicalNodeList = Ntk_NetworkComputeTopologicalOrder(network, 00706 rootNodesArray, 00707 leafNodesTable); 00708 00709 st_free_table(leafNodesTable); 00710 00711 00712 /* Go through the topologicalNodeList 00713 * a. If the node is of combinational input type, continue. 00714 * 00715 * b. Otherwise, Build the Mdd for this node, in terms of the function of the 00716 * fanin nodes in. If the Mdd size exceeds the threshold, create an Mdd ID 00717 * for this node. 00718 */ 00719 00720 lsForEachItem(topologicalNodeList, lsgen, node){ 00721 if (st_is_member(nodeToMvfTable, node)) continue; 00722 name = Ntk_NodeReadName(node); 00723 flag = st_lookup(PartPartitionReadNameToVertex(partition), 00724 name, &vertex); 00725 if (flag) { 00726 mddId = Ntk_NodeReadMddId(node); 00727 if (mddId != -1) 00728 st_insert(nodeToMvfTable, node, 00729 (char *)Mvf_FunctionCreateFromVariable(mddManager,mddId)); 00730 else { 00731 nodeMvf = PartVertexReadFunction(vertex); 00732 st_insert(nodeToMvfTable, node, nodeMvf); 00733 } 00734 continue; 00735 } 00736 nodeMvf = NodeBuildMvf(node, nodeToMvfTable); 00737 bddSize = bdd_size_multiple(nodeMvf); 00738 if ((bddSize <= sizeThreshold) && 00739 (Ntk_NodeTestIsCombOutput(node) == 0)){ 00740 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 00741 continue; 00742 } 00743 /* node either is a primary output, or has an mvf exceeding the 00744 threshold. */ 00745 vertex = g_add_vertex(partition); 00746 name = Ntk_NodeReadName(node); 00747 st_insert(PartPartitionReadNameToVertex(partition), name, 00748 (char *)vertex); 00749 if ((bddSize > sizeThreshold) && 00750 (Ntk_NodeReadNumFanouts(node) != 0)){ 00751 if ((mddId = Ntk_NodeReadMddId(node)) == -1){ 00752 Ord_NetworkAssignMddIdForNode(network, node); 00753 mddId = Ntk_NodeReadMddId(node); 00754 } 00755 st_insert(nodeToMvfTable, (char *)node, 00756 (char *)Mvf_FunctionCreateFromVariable(mddManager,mddId)); 00757 } 00758 else { 00759 /* Small mvf, or no fanout */ 00760 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 00761 } 00762 mddId = Ntk_NodeReadMddId(node); 00763 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, 00764 nodeMvf, 00765 mddId); 00766 if (mddId != -1){ 00767 st_insert(PartPartitionReadMddIdToVertex(partition), 00768 (char *)(long)mddId, (char *)vertex); 00769 } 00770 }/* for each member of topologicalNodeList */ 00771 00772 /* 00773 * Free the Mvfs in nodeToMvfTable not associated with vertices in the 00774 * partition. The mvfs of inputs are always in the partition; hence, 00775 * their mvfs should always be preserved. For outputs, we have to free 00776 * the mvf in nodeToMvfTable if the output is also a cutpoint, because in 00777 * this case the mvf in the partition vertex and the one in the 00778 * nodeToMvfTable are different. 00779 */ 00780 00781 lsForEachItem(topologicalNodeList, gen, node){ 00782 if (!Ntk_NodeTestIsCombInput(node)){ 00783 if(!Ntk_NodeTestIsCombOutput(node)){ 00784 st_lookup(nodeToMvfTable, node, &nodeMvf); 00785 assert(nodeMvf != NIL(Mvf_Function_t)); 00786 Mvf_FunctionFree(nodeMvf); 00787 } else { 00788 Mvf_Function_t *vertexMvf; 00789 00790 name = Ntk_NodeReadName(node); 00791 vertex = Part_PartitionFindVertexByName(partition, name); 00792 st_lookup(nodeToMvfTable, node, &nodeMvf); 00793 vertexMvf = PartVertexReadFunction(vertex); 00794 assert(nodeMvf != NIL(Mvf_Function_t) && 00795 vertexMvf != NIL(Mvf_Function_t)); 00796 if(vertexMvf != nodeMvf){ 00797 Mvf_FunctionFree(nodeMvf); 00798 } 00799 } 00800 }/* not input */ 00801 }/* for each node */ 00802 00803 PartitionCreateEdges(partition); 00804 array_free(rootNodesArray); 00805 st_free_table(nodeToMvfTable); 00806 lsDestroy(topologicalNodeList, (void (*)(lsGeneric))0); 00807 } 00808 00825 void 00826 PartInsertBnvs( 00827 Ntk_Network_t *network, 00828 st_table *coiLatchTable, 00829 st_table *coiBnvTable) 00830 { 00831 mdd_manager *mddManager = Ntk_NetworkReadMddManager(network); 00832 st_table *nodeToMvfTable = st_init_table(st_ptrcmp, st_ptrhash); 00833 st_table *leafNodesTable = st_init_table(st_ptrcmp, st_ptrhash); 00834 lsList topologicalNodeList; 00835 st_table *topoNodeTable; 00836 array_t *rootNodesArray; 00837 Ntk_Node_t *fanoutNode, *node; 00838 Mvf_Function_t *nodeMvf; 00839 long bddSize, sizeThreshold, fanoutNumber, mddId; 00840 int i; 00841 lsGen lsgen; 00842 st_generator *stgen; 00843 char *flagValue; 00844 00845 flagValue = Cmd_FlagReadByName("partition_threshold"); 00846 if (flagValue == NIL(char)){ 00847 sizeThreshold = 1000; /* the default value */ 00848 } 00849 else { 00850 sizeThreshold = atoi(flagValue); 00851 } 00852 00853 /* Put latch data inputs in the rootNodesArray */ 00854 rootNodesArray = array_alloc(Ntk_Node_t *, 0); 00855 st_foreach_item(coiLatchTable, stgen, &node, NULL) { 00856 array_insert_last(Ntk_Node_t *, rootNodesArray, 00857 Ntk_LatchReadDataInput(node)); 00858 array_insert_last(Ntk_Node_t *, rootNodesArray, 00859 Ntk_LatchReadInitialInput(node)); 00860 } 00861 00862 /* Put combinational inputs, as well as the existing coiBnvs, in the 00863 * leafNodesTable. */ 00864 Ntk_NetworkForEachCombInput(network, lsgen, node) { 00865 st_insert(leafNodesTable, node, (char *) (long) (-1) ); 00866 } 00867 st_foreach_item(coiBnvTable, stgen, &node, NULL) { 00868 st_insert(leafNodesTable, node, (char *) (long) (-1) ); 00869 } 00870 00871 /* Get an array of nodes sorted in topological order */ 00872 topologicalNodeList = Ntk_NetworkComputeTopologicalOrder(network, 00873 rootNodesArray, 00874 leafNodesTable); 00875 00876 /* For each node, compute the number of fanouts */ 00877 topoNodeTable = st_init_table(st_ptrcmp, st_ptrhash); 00878 lsForEachItem(topologicalNodeList, lsgen, node){ 00879 st_insert(topoNodeTable, (char *)node, NIL(char)); 00880 } 00881 lsForEachItem(topologicalNodeList, lsgen, node){ 00882 fanoutNumber = 0; 00883 Ntk_NodeForEachFanout(node, i, fanoutNode) { 00884 if (st_is_member(topoNodeTable, (char *)fanoutNode) && 00885 !st_is_member(leafNodesTable, (char *)fanoutNode) ) 00886 fanoutNumber++; 00887 } 00888 st_insert(topoNodeTable, (char *)node, (char *)fanoutNumber); 00889 } 00890 00891 /* assign mddIds to latches if necessary */ 00892 /* chao: this may be too slow! */ 00893 /* chao: this order may not be as good as static_order */ 00894 lsForEachItem(topologicalNodeList, lsgen, node){ 00895 if (Ntk_NodeTestIsInput(node)) { 00896 Ord_NetworkAssignMddIdForNode(network, node); 00897 }else if (Ntk_NodeTestIsLatch(node)) { 00898 Ord_NetworkAssignMddIdForNode(network, node); 00899 Ord_NetworkAssignMddIdForNode(network, Ntk_NodeReadShadow(node)); 00900 } 00901 } 00902 st_foreach_item(coiLatchTable, stgen, &node, NULL) { 00903 Ord_NetworkAssignMddIdForNode(network, node); 00904 Ord_NetworkAssignMddIdForNode(network, Ntk_NodeReadShadow(node)); 00905 } 00906 00907 /* create nodeMvf for leaf nodes */ 00908 st_foreach_item(leafNodesTable, stgen, &node, NULL) { 00909 if (!st_lookup(topoNodeTable, node, &fanoutNumber)) { 00910 continue; 00911 } 00912 mddId = Ntk_NodeReadMddId(node); 00913 assert(mddId != NTK_UNASSIGNED_MDD_ID); 00914 00915 if (Ntk_NodeTestIsPseudoInput(node)){ 00916 nodeMvf = NodeBuildPseudoInputMvf(node); 00917 } 00918 else { 00919 nodeMvf = Mvf_FunctionCreateFromVariable(mddManager,mddId); 00920 } 00921 00922 if (fanoutNumber <= 0) { 00923 Mvf_FunctionFree(nodeMvf); 00924 st_insert(nodeToMvfTable, (char *)node, NIL(char)); 00925 } 00926 else 00927 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 00928 } 00929 00930 st_free_table(leafNodesTable); 00931 00932 00933 /* Go through the topologicalNodeList 00934 * a. If the node is of combinational input type, continue. 00935 * 00936 * b. Otherwise, Build the Mdd for this node, in terms of the function of the 00937 * fanin nodes in. If the Mdd size exceeds the threshold, create an Mdd ID 00938 * for this node. 00939 */ 00940 lsForEachItem(topologicalNodeList, lsgen, node){ 00941 if (st_is_member(nodeToMvfTable, node)) 00942 continue; 00943 00944 nodeMvf = NodeBuildMvf2(node, nodeToMvfTable, topoNodeTable); 00945 bddSize = bdd_size_multiple(nodeMvf); 00946 st_lookup(topoNodeTable, node, &fanoutNumber); 00947 00948 if ((bddSize <= sizeThreshold) && !Ntk_NodeTestIsCombOutput(node)) { 00949 assert(fanoutNumber > 0); 00950 st_insert(nodeToMvfTable, node, nodeMvf); 00951 continue; 00952 } 00953 /* node either is a primary output, or has an mvf exceeding the 00954 threshold. */ 00955 if ((bddSize > sizeThreshold) && fanoutNumber > 0) { 00956 /*(Ntk_NodeReadNumFanouts(node) != 0)) { */ 00957 /* ADD A bnv !!! */ 00958 st_insert(coiBnvTable, (char *)node, NIL(char)); 00959 00960 if ((mddId = Ntk_NodeReadMddId(node)) == -1){ 00961 Ord_NetworkAssignMddIdForNode(network, node); 00962 mddId = Ntk_NodeReadMddId(node); 00963 } 00964 00965 st_insert(nodeToMvfTable, (char *)node, 00966 (char *)Mvf_FunctionCreateFromVariable(mddManager,mddId)); 00967 Mvf_FunctionFree(nodeMvf); 00968 }else { 00969 if (fanoutNumber <= 0) { 00970 Mvf_FunctionFree(nodeMvf); 00971 st_insert(nodeToMvfTable, node, NIL(char)); 00972 } 00973 else 00974 st_insert(nodeToMvfTable, node, (char *)nodeMvf); 00975 } 00976 00977 }/* for each member of topologicalNodeList */ 00978 00979 /* sanity check */ 00980 st_foreach_item(nodeToMvfTable, stgen, &node, &nodeMvf) { 00981 #if 0 00982 if (nodeMvf != NIL(Mvf_Function_t)) { 00983 st_lookup(topoNodeTable, node, &fanoutNumber); 00984 fprintf(vis_stdout, "\nunclean node = %s, fanout# = %d", 00985 Ntk_NodeReadName(node), fanoutNumber); 00986 } 00987 #else 00988 assert (nodeMvf == NIL(Mvf_Function_t)); 00989 #endif 00990 } 00991 00992 array_free(rootNodesArray); 00993 st_free_table(nodeToMvfTable); 00994 st_free_table(topoNodeTable); 00995 lsDestroy(topologicalNodeList, (void (*)(lsGeneric))0); 00996 } 00997 01014 void 01015 PartPartitionWithExistingBnvs( 01016 Ntk_Network_t *network, 01017 graph_t *partition, 01018 st_table *coiBnvTable, 01019 st_table *absLatchTable, 01020 st_table *absBnvTable) 01021 { 01022 mdd_manager *mddManager = PartPartitionReadMddManager(partition); 01023 st_table *nodeToMvfTable = st_init_table(st_ptrcmp, st_ptrhash); 01024 st_table *leafNodesTable = st_init_table(st_ptrcmp, st_ptrhash); 01025 array_t *rootNodesArray, *combNodesArray; 01026 lsList topologicalNodeList; 01027 st_table *topoNodeTable; 01028 Ntk_Node_t *fanoutNode, *node; 01029 Mvf_Function_t *nodeMvf; 01030 vertex_t *vertex; 01031 long mddId, fanoutNumber; 01032 char *name; 01033 lsGen lsgen; 01034 st_generator *stgen; 01035 int i; 01036 01037 /* Put latch data inputs in the rootNodesArray */ 01038 rootNodesArray = array_alloc(Ntk_Node_t *, 0); 01039 st_foreach_item(absLatchTable, stgen, &node, NULL) { 01040 array_insert_last(Ntk_Node_t *, rootNodesArray, 01041 Ntk_LatchReadDataInput(node)); 01042 array_insert_last(Ntk_Node_t *, rootNodesArray, 01043 Ntk_LatchReadInitialInput(node)); 01044 } 01045 01046 /* Put also latch initial inputs in the rootNodesArray */ 01047 combNodesArray = Ntk_NodeComputeTransitiveFaninNodes(network, 01048 rootNodesArray, 01049 TRUE, TRUE); 01050 arrayForEachItem(Ntk_Node_t *, combNodesArray, i, node) { 01051 if ( Ntk_NodeTestIsLatch(node) && 01052 !st_is_member(absLatchTable, (char *)node) ) 01053 array_insert_last(Ntk_Node_t *, rootNodesArray, 01054 Ntk_LatchReadInitialInput(node)); 01055 } 01056 array_free(combNodesArray); 01057 01058 01059 /* Put combinational inputs in the leafNodesTable. */ 01060 Ntk_NetworkForEachCombInput(network, lsgen, node) { 01061 st_insert(leafNodesTable, (char *)node, (char *) (long) (-1) ); 01062 } 01063 /* Put BNVs that are not in absBnvTable in the leafNodesTable */ 01064 st_foreach_item(coiBnvTable, stgen, &node, NULL) { 01065 if (!st_is_member(absBnvTable, (char *)node)) 01066 st_insert(leafNodesTable, node, (char *) (long) (-1) ); 01067 } 01068 01069 /* Get an array of nodes sorted in topological order */ 01070 topologicalNodeList = Ntk_NetworkComputeTopologicalOrder(network, 01071 rootNodesArray, 01072 leafNodesTable); 01073 01074 /* For each node, compute the number of fanouts */ 01075 topoNodeTable = st_init_table(st_ptrcmp, st_ptrhash); 01076 lsForEachItem(topologicalNodeList, lsgen, node){ 01077 st_insert(topoNodeTable, (char *)node, NIL(char)); 01078 } 01079 lsForEachItem(topologicalNodeList, lsgen, node){ 01080 fanoutNumber = 0; 01081 Ntk_NodeForEachFanout(node, i, fanoutNode) { 01082 if (st_is_member(topoNodeTable, (char *)fanoutNode) && 01083 !st_is_member(leafNodesTable, (char *)fanoutNode)) 01084 fanoutNumber++; 01085 } 01086 st_insert(topoNodeTable, (char *)node, (char *)fanoutNumber); 01087 } 01088 01089 /* Create partition vertices for the leaves 01090 */ 01091 st_foreach_item(leafNodesTable, stgen, &node, NULL){ 01092 if (!st_lookup(topoNodeTable, node, &fanoutNumber)) 01093 continue; 01094 mddId = Ntk_NodeReadMddId(node); 01095 if (mddId == NTK_UNASSIGNED_MDD_ID) { 01096 /* it is a input sign under the fanin cone of the initialInput 01097 * of some invisible latches */ 01098 assert(Ntk_NodeTestIsInput(node)); 01099 Ord_NetworkAssignMddIdForNode(network, node); 01100 mddId = Ntk_NodeReadMddId(node); 01101 } 01102 /*assert(mddId != NTK_UNASSIGNED_MDD_ID);*/ 01103 vertex = g_add_vertex(partition); 01104 name = Ntk_NodeReadName(node); 01105 st_insert(PartPartitionReadNameToVertex(partition), name, (char *)vertex); 01106 st_insert(PartPartitionReadMddIdToVertex(partition), (char *)(long)mddId, 01107 (char *)vertex); 01108 if (Ntk_NodeTestIsPseudoInput(node)){ 01109 nodeMvf = NodeBuildPseudoInputMvf(node); 01110 } 01111 else { 01112 nodeMvf = Mvf_FunctionCreateFromVariable(mddManager,mddId); 01113 } 01114 01115 if (fanoutNumber <= 0) 01116 st_insert(nodeToMvfTable, (char *)node, NIL(char)); 01117 else 01118 st_insert(nodeToMvfTable, (char *)node, 01119 (char *)Mvf_FunctionDuplicate(nodeMvf)); 01120 01121 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, nodeMvf, 01122 mddId); 01123 } 01124 01125 /* Go through the topologicalNodeList, and build Mdds for nodes in 01126 * the absBnvTable 01127 */ 01128 lsForEachItem(topologicalNodeList, lsgen, node){ 01129 if (st_is_member(nodeToMvfTable, (char *)node)) continue; 01130 01131 nodeMvf = NodeBuildMvf2(node, nodeToMvfTable, topoNodeTable); 01132 01133 if ( !st_is_member(absBnvTable,(char *)node) && 01134 !Ntk_NodeTestIsCombOutput(node)) { 01135 st_insert(nodeToMvfTable, (char *)node, (char *)nodeMvf); 01136 continue; 01137 } 01138 01139 /* node is either a primary output, or a boolean network var */ 01140 vertex = g_add_vertex(partition); 01141 name = Ntk_NodeReadName(node); 01142 st_insert(PartPartitionReadNameToVertex(partition), name, (char *)vertex); 01143 01144 if (st_is_member(absBnvTable,node)) { 01145 /* ADD a bnv !!! */ 01146 mddId = Ntk_NodeReadMddId(node); 01147 assert(mddId != -1); 01148 st_insert(nodeToMvfTable, node, 01149 (char *)Mvf_FunctionCreateFromVariable(mddManager,mddId)); 01150 }else { 01151 st_lookup(topoNodeTable, node, &fanoutNumber); 01152 if (fanoutNumber <= 0) 01153 st_insert(nodeToMvfTable, node, NIL(char)); 01154 else 01155 st_insert(nodeToMvfTable, node, 01156 (char *)Mvf_FunctionDuplicate(nodeMvf)); 01157 } 01158 01159 mddId = Ntk_NodeReadMddId(node); 01160 vertex->user_data = (gGeneric)PartVertexInfoCreateSingle(name, nodeMvf, 01161 mddId); 01162 if (mddId != -1){ 01163 st_insert(PartPartitionReadMddIdToVertex(partition), 01164 (char *)(long)mddId, (char *)vertex); 01165 } 01166 }/* for each member of topologicalNodeList */ 01167 01168 /* sanity check */ 01169 st_foreach_item(nodeToMvfTable, stgen, &node, &nodeMvf) { 01170 #if 1 01171 if (nodeMvf != NIL(Mvf_Function_t)) { 01172 st_lookup(topoNodeTable, node, &fanoutNumber); 01173 fprintf(vis_stdout, "\nunclean node = %s, fanout# = %ld", 01174 Ntk_NodeReadName(node), fanoutNumber); 01175 } 01176 #else 01177 assert(nodeMvf == NIL(Mvf_Function_t)); 01178 #endif 01179 } 01180 01181 PartitionCreateEdges(partition); 01182 array_free(rootNodesArray); 01183 st_free_table(nodeToMvfTable); 01184 st_free_table(topoNodeTable); 01185 st_free_table(leafNodesTable); 01186 lsDestroy(topologicalNodeList, (void (*)(lsGeneric))0); 01187 } 01188 01189 01199 void 01200 PartPrintPartition(graph_t *partition) 01201 { 01202 vertex_t *vertex; 01203 lsList vertexList = g_get_vertices(partition); 01204 lsGen gen; 01205 st_table *vertexTable = st_init_table(st_ptrcmp, st_ptrhash); 01206 fprintf(vis_stdout,"******* Printing Partition *********\n"); 01207 lsForEachItem(vertexList, gen, vertex){ 01208 PrintPartitionRecursively(vertex,vertexTable,0); 01209 } 01210 fprintf(vis_stdout,"******* End Printing Partition *********\n"); 01211 st_free_table(vertexTable); 01212 } 01213 01214 01215 /*---------------------------------------------------------------------------*/ 01216 /* Definition of static functions */ 01217 /*---------------------------------------------------------------------------*/ 01218 01232 static void 01233 PartitionCreateEdges(graph_t *partition) 01234 { 01235 lsList vertexList; 01236 lsGen gen; 01237 vertex_t *toVertex; 01238 edge_t *edge; 01239 01240 /* this will be executed only when used inside PartitionUpdateFrontier */ 01241 foreach_edge(partition, gen, edge) { 01242 g_delete_edge(edge, (void(*)(gGeneric))0); 01243 } 01244 01245 vertexList = g_get_vertices(partition); 01246 01247 lsForEachItem(vertexList, gen, toVertex) { 01248 st_table *mddSupport; /* To store the support of the Mvf_Function */ 01249 st_generator *stGen; /* To iterate over the MddIds of the support */ 01250 vertex_t *fromVertex; /* Will hold the current vertex in the support */ 01251 Mvf_Function_t *mddFunction; 01252 long mddId; 01253 01254 mddFunction = PartVertexReadFunction(toVertex); 01255 mddSupport = PartCreateFunctionSupportTable(mddFunction); 01256 st_foreach_item(mddSupport, stGen, &mddId, NULL) { 01257 st_lookup(PartPartitionReadMddIdToVertex(partition), (char *) mddId, 01258 &fromVertex); 01259 /* 01260 * Add the edge to the graph. Make sure a self loop is not added. The 01261 * self loop may be produced by a mdd that has in its support the same 01262 * variables that represent the mddId of the node. 01263 */ 01264 if (fromVertex != toVertex) { 01265 g_add_edge(fromVertex, toVertex); 01266 } 01267 } 01268 st_free_table(mddSupport); 01269 } 01270 } 01271 01285 static Mvf_Function_t * 01286 NodeBuildMvf(Ntk_Node_t * node, st_table * nodeToMvfTable) 01287 { 01288 int i; 01289 Mvf_Function_t *resultMvf; 01290 Ntk_Node_t *faninNode; 01291 array_t *faninMvfs = array_alloc(Mvf_Function_t *, 01292 Ntk_NodeReadNumFanins(node)); 01293 mdd_manager *mddMgr = Ntk_NetworkReadMddManager(Ntk_NodeReadNetwork(node)); 01294 int columnIndex = Ntk_NodeReadOutputIndex(node); 01295 Tbl_Table_t *table = Ntk_NodeReadTable(node); 01296 01297 Ntk_NodeForEachFanin(node, i, faninNode) { 01298 Mvf_Function_t *tmpMvf; 01299 st_lookup(nodeToMvfTable, faninNode, &tmpMvf); 01300 assert(tmpMvf); 01301 array_insert(Mvf_Function_t *, faninMvfs, i, tmpMvf); 01302 } 01303 01304 resultMvf = Tbl_TableBuildMvfFromFanins(table, columnIndex, 01305 faninMvfs, mddMgr); 01306 01307 /* Don't free the MVFs themselves, but just free the array. */ 01308 array_free(faninMvfs); 01309 return resultMvf; 01310 } 01311 01326 static Mvf_Function_t * 01327 NodeBuildMvf2( 01328 Ntk_Node_t * node, 01329 st_table * nodeToMvfTable, 01330 st_table * faninNumberTable) 01331 { 01332 long faninNumber; 01333 int i; 01334 Mvf_Function_t *resultMvf; 01335 Ntk_Node_t *faninNode; 01336 array_t *faninMvfs = array_alloc(Mvf_Function_t *, 01337 Ntk_NodeReadNumFanins(node)); 01338 mdd_manager *mddMgr = Ntk_NetworkReadMddManager(Ntk_NodeReadNetwork(node)); 01339 int columnIndex = Ntk_NodeReadOutputIndex(node); 01340 Tbl_Table_t *table = Ntk_NodeReadTable(node); 01341 01342 Ntk_NodeForEachFanin(node, i, faninNode) { 01343 Mvf_Function_t *tmpMvf; 01344 st_lookup(nodeToMvfTable, faninNode, &tmpMvf); 01345 assert(tmpMvf); 01346 array_insert(Mvf_Function_t *, faninMvfs, i, tmpMvf); 01347 } 01348 01349 resultMvf = Tbl_TableBuildMvfFromFanins(table, columnIndex, 01350 faninMvfs, mddMgr); 01351 01352 /* Don't free the MVFs themselves, but just free the array. */ 01353 array_free(faninMvfs); 01354 01355 /* if the fanin node is no longer useful, remove its Mvfs */ 01356 Ntk_NodeForEachFanin(node, i, faninNode) { 01357 st_lookup(faninNumberTable, faninNode, &faninNumber); 01358 assert(faninNumber > 0); 01359 faninNumber--; 01360 st_insert(faninNumberTable, faninNode, (char *)faninNumber); 01361 01362 if (faninNumber <= 0) { 01363 Mvf_Function_t *tmpMvf; 01364 st_lookup(nodeToMvfTable, faninNode, &tmpMvf); 01365 Mvf_FunctionFree(tmpMvf); 01366 st_insert(nodeToMvfTable, faninNode, NIL(char)); 01367 } 01368 } 01369 01370 return resultMvf; 01371 } 01372 01373 01374 01394 static Mvf_Function_t * 01395 NodeBuildPseudoInputMvf( 01396 Ntk_Node_t * node) 01397 { 01398 mdd_manager *mddMgr = Ntk_NetworkReadMddManager(Ntk_NodeReadNetwork(node)); 01399 int mddId = Ntk_NodeReadMddId( node ); 01400 int columnIndex = Ntk_NodeReadOutputIndex( node ); 01401 Tbl_Table_t *table = Ntk_NodeReadTable( node ); 01402 Mvf_Function_t *mvf = Tbl_TableBuildNonDetConstantMvf(table, columnIndex, 01403 mddId, mddMgr); 01404 01405 mdd_t *vMdd, *tMdd, *rMdd; 01406 int lIndex, needProcess, i; 01407 01408 rMdd = mdd_zero(mddMgr); 01409 needProcess = 0; 01410 lIndex = 0; 01411 for(i=0; i<mvf->num; i++) { 01412 vMdd = array_fetch(mdd_t *, mvf, i); 01413 if(mdd_equal(vMdd, rMdd)) { 01414 needProcess = 1; 01415 } 01416 else { 01417 lIndex = i; 01418 } 01419 } 01420 if(needProcess) { 01421 for(i=0; i<lIndex; i++) { 01422 vMdd = array_fetch(mdd_t *, mvf, i); 01423 tMdd = mdd_or(vMdd, rMdd, 1, 1); 01424 mdd_free(rMdd); 01425 rMdd = tMdd; 01426 } 01427 vMdd = array_fetch(mdd_t *, mvf, lIndex); 01428 mdd_free(vMdd); 01429 tMdd = mdd_not(rMdd); 01430 mdd_free(rMdd); 01431 array_insert(mdd_t *, mvf, lIndex, tMdd); 01432 } 01433 else { 01434 mdd_free(rMdd); 01435 } 01436 01437 return mvf; 01438 } 01439 01440 01450 static void 01451 PrintPartitionRecursively(vertex_t *vertex, st_table *vertexTable, int 01452 indent) 01453 { 01454 int i; 01455 lsList faninEdges; 01456 lsGen gen; 01457 vertex_t *faninVertex; 01458 edge_t *faninEdge; 01459 01460 if (st_is_member(vertexTable, (char *)vertex)) return; 01461 st_insert(vertexTable, (char *)vertex, NIL(char)); 01462 for(i=0; i<= indent; i++) fprintf(vis_stdout," "); 01463 fprintf(vis_stdout,"%s %d\n", Part_VertexReadName(vertex), 01464 Part_VertexReadMddId(vertex)); 01465 faninEdges = g_get_in_edges(vertex); 01466 if (lsLength(faninEdges) == 0) return; 01467 lsForEachItem(faninEdges, gen, faninEdge){ 01468 faninVertex = g_e_source(faninEdge); 01469 PrintPartitionRecursively(faninVertex, vertexTable,indent+2); 01470 } 01471 } 01472