00001
00021 #include "abc.h"
00022 #include "fraig.h"
00023
00027
00028 static void Abc_NtkFraigSweepUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
00029 static stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose, int fVeryVerbose );
00030 static void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose );
00031 static void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose );
00032 static void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose );
00033 static int Abc_NodeDroppingCost( Abc_Obj_t * pNode );
00034
00035 static int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes );
00036 static void Abc_NodeSweep( Abc_Obj_t * pNode, int fVerbose );
00037 static void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 );
00038 static void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin );
00039
00043
00057 bool Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose, int fVeryVerbose )
00058 {
00059 Fraig_Params_t Params;
00060 Abc_Ntk_t * pNtkAig;
00061 Fraig_Man_t * pMan;
00062 stmm_table * tEquiv;
00063 Abc_Obj_t * pObj;
00064 int i, fUseTrick;
00065
00066 assert( !Abc_NtkIsStrash(pNtk) );
00067
00068
00069 fUseTrick = 0;
00070 if ( Abc_NtkIsMappedLogic(pNtk) )
00071 {
00072 fUseTrick = 1;
00073 Abc_NtkForEachNode( pNtk, pObj, i )
00074 pObj->pNext = pObj->pData;
00075 }
00076
00077 pNtkAig = Abc_NtkStrash( pNtk, 0, 1, 0 );
00078
00079 if ( fUseTrick )
00080 {
00081 extern void * Abc_FrameReadLibGen();
00082 Hop_ManStop( pNtk->pManFunc );
00083 pNtk->pManFunc = Abc_FrameReadLibGen();
00084 pNtk->ntkFunc = ABC_FUNC_MAP;
00085 Abc_NtkForEachNode( pNtk, pObj, i )
00086 pObj->pData = pObj->pNext, pObj->pNext = NULL;
00087 }
00088
00089
00090 Fraig_ParamsSetDefault( &Params );
00091 pMan = Abc_NtkToFraig( pNtkAig, &Params, 0, 0 );
00092
00093
00094
00095
00096 if ( fExdc )
00097 {
00098 if ( pNtk->pExdc == NULL )
00099 printf( "Warning: Networks has no EXDC.\n" );
00100 else
00101 Abc_NtkFraigSweepUsingExdc( pMan, pNtk );
00102 }
00103
00104 Abc_NtkLevel( pNtk );
00105
00106
00107 tEquiv = Abc_NtkFraigEquiv( pNtk, fUseInv, fVerbose, fVeryVerbose );
00108
00109
00110 Abc_NtkFraigTransform( pNtk, tEquiv, fUseInv, fVerbose );
00111 stmm_free_table( tEquiv );
00112
00113
00114 Fraig_ManFree( pMan );
00115 Abc_NtkDelete( pNtkAig );
00116
00117
00118 if ( Abc_NtkHasMapping(pNtk) )
00119 Abc_NtkCleanup( pNtk, fVerbose );
00120 else
00121 Abc_NtkSweep( pNtk, fVerbose );
00122
00123
00124 if ( !Abc_NtkCheck( pNtk ) )
00125 {
00126 printf( "Abc_NtkFraigSweep: The network check has failed.\n" );
00127 return 0;
00128 }
00129 return 1;
00130 }
00131
00143 void Abc_NtkFraigSweepUsingExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk )
00144 {
00145 Fraig_Node_t * gNodeExdc, * gNode, * gNodeRes;
00146 Abc_Obj_t * pNode, * pNodeAig;
00147 int i;
00148 extern Fraig_Node_t * Abc_NtkToFraigExdc( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkExdc );
00149
00150 assert( pNtk->pExdc );
00151
00152 gNodeExdc = Abc_NtkToFraigExdc( pMan, pNtk, pNtk->pExdc );
00153
00154 Abc_NtkForEachNode( pNtk, pNode, i )
00155 {
00156
00157 if ( Abc_ObjFaninNum(pNode) == 0 )
00158 continue;
00159
00160 pNodeAig = pNode->pCopy;
00161
00162 if ( pNodeAig == NULL )
00163 continue;
00164
00165 gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) );
00166
00167 gNodeRes = Fraig_NodeAnd( pMan, gNode, Fraig_Not(gNodeExdc) );
00168
00169 Abc_ObjRegular(pNodeAig)->pCopy = (Abc_Obj_t *)Fraig_NotCond( gNodeRes, Abc_ObjIsComplement(pNodeAig) );
00170 }
00171 }
00172
00184 stmm_table * Abc_NtkFraigEquiv( Abc_Ntk_t * pNtk, int fUseInv, int fVerbose, int fVeryVerbose )
00185 {
00186 Abc_Obj_t * pList, * pNode, * pNodeAig;
00187 Fraig_Node_t * gNode;
00188 Abc_Obj_t ** ppSlot;
00189 stmm_table * tStrash2Net;
00190 stmm_table * tResult;
00191 stmm_generator * gen;
00192 int c, Counter;
00193
00194
00195 tStrash2Net = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
00196 Abc_NtkForEachNode( pNtk, pNode, c )
00197 {
00198
00199 if ( Abc_ObjFaninNum(pNode) == 0 )
00200 continue;
00201
00202 pNodeAig = pNode->pCopy;
00203
00204 if ( pNodeAig == NULL )
00205 continue;
00206
00207 if ( Abc_NodeFindCoFanout(pNode) )
00208 continue;
00209
00210 gNode = Fraig_NotCond( Abc_ObjRegular(pNodeAig)->pCopy, Abc_ObjIsComplement(pNodeAig) );
00211 if ( !stmm_find_or_add( tStrash2Net, (char *)Fraig_Regular(gNode), (char ***)&ppSlot ) )
00212 *ppSlot = NULL;
00213
00214 pNode->pNext = *ppSlot;
00215 *ppSlot = pNode;
00216
00217 pNode->fPhase = Fraig_IsComplement(gNode);
00218 }
00219
00220
00221 c = 0;
00222 Counter = 0;
00223 tResult = stmm_init_table(stmm_ptrcmp,stmm_ptrhash);
00224 stmm_foreach_item( tStrash2Net, gen, (char **)&gNode, (char **)&pList )
00225 {
00226
00227 if ( pList == NULL || pList->pNext == NULL )
00228 continue;
00229
00230 stmm_insert( tResult, (char *)pList, NULL );
00231
00232 for ( pNode = pList; pNode; pNode = pNode->pNext )
00233 Counter++;
00234
00235 if ( fVeryVerbose )
00236 {
00237 printf( "Class %2d : {", c );
00238 for ( pNode = pList; pNode; pNode = pNode->pNext )
00239 {
00240 pNode->pCopy = NULL;
00241 printf( " %s", Abc_ObjName(pNode) );
00242 printf( "(%c)", pNode->fPhase? '-' : '+' );
00243 printf( "(%d)", pNode->Level );
00244 }
00245 printf( " }\n" );
00246 c++;
00247 }
00248 }
00249 if ( fVerbose || fVeryVerbose )
00250 {
00251 printf( "Sweeping stats for network \"%s\":\n", pNtk->pName );
00252 printf( "Internal nodes = %d. Different functions (up to compl) = %d.\n", Abc_NtkNodeNum(pNtk), stmm_count(tStrash2Net) );
00253 printf( "Non-trivial classes = %d. Nodes in non-trivial classes = %d.\n", stmm_count(tResult), Counter );
00254 }
00255 stmm_free_table( tStrash2Net );
00256 return tResult;
00257 }
00258
00259
00271 void Abc_NtkFraigTransform( Abc_Ntk_t * pNtk, stmm_table * tEquiv, int fUseInv, bool fVerbose )
00272 {
00273 stmm_generator * gen;
00274 Abc_Obj_t * pList;
00275 if ( stmm_count(tEquiv) == 0 )
00276 return;
00277
00278 if ( Abc_NtkHasMapping( pNtk ) )
00279 {
00280 Abc_NtkDelayTrace( pNtk );
00281 stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL )
00282 Abc_NtkFraigMergeClassMapped( pNtk, pList, fUseInv, fVerbose );
00283 }
00284 else
00285 {
00286 stmm_foreach_item( tEquiv, gen, (char **)&pList, NULL )
00287 Abc_NtkFraigMergeClass( pNtk, pList, fUseInv, fVerbose );
00288 }
00289 }
00290
00291
00303 void Abc_NtkFraigMergeClassMapped( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose )
00304 {
00305 Abc_Obj_t * pListDir, * pListInv;
00306 Abc_Obj_t * pNodeMin, * pNode, * pNext;
00307 float Arrival1, Arrival2;
00308
00309 assert( pChain );
00310 assert( pChain->pNext );
00311
00312
00313
00314 pListDir = pListInv = NULL;
00315 for ( pNode = pChain, pNext = pChain->pNext;
00316 pNode;
00317 pNode = pNext, pNext = pNode? pNode->pNext : NULL )
00318 {
00319
00320 if ( pNode->fPhase == 1 )
00321 {
00322 pNode->pNext = pListDir;
00323 pListDir = pNode;
00324 }
00325 else
00326 {
00327 pNode->pNext = pListInv;
00328 pListInv = pNode;
00329 }
00330 }
00331
00332
00333 pNodeMin = pListDir;
00334 for ( pNode = pListDir; pNode; pNode = pNode->pNext )
00335 {
00336 Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
00337 Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
00338
00339
00340 if ( Arrival1 > Arrival2 ||
00341 Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
00342 Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
00343 Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) )
00344 pNodeMin = pNode;
00345 }
00346
00347
00348 for ( pNode = pListDir; pNode; pNode = pNode->pNext )
00349 if ( pNode != pNodeMin )
00350 Abc_ObjTransferFanout( pNode, pNodeMin );
00351
00352
00353 pNodeMin = pListInv;
00354 for ( pNode = pListInv; pNode; pNode = pNode->pNext )
00355 {
00356 Arrival1 = Abc_NodeReadArrival(pNodeMin)->Worst;
00357 Arrival2 = Abc_NodeReadArrival(pNode )->Worst;
00358
00359
00360 if ( Arrival1 > Arrival2 ||
00361 Arrival1 == Arrival2 && pNodeMin->Level > pNode->Level ||
00362 Arrival1 == Arrival2 && pNodeMin->Level == pNode->Level &&
00363 Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) )
00364 pNodeMin = pNode;
00365 }
00366
00367
00368 for ( pNode = pListInv; pNode; pNode = pNode->pNext )
00369 if ( pNode != pNodeMin )
00370 Abc_ObjTransferFanout( pNode, pNodeMin );
00371 }
00372
00385 void Abc_NtkFraigMergeClass( Abc_Ntk_t * pNtk, Abc_Obj_t * pChain, int fUseInv, int fVerbose )
00386 {
00387 Abc_Obj_t * pListDir, * pListInv;
00388 Abc_Obj_t * pNodeMin, * pNodeMinInv;
00389 Abc_Obj_t * pNode, * pNext;
00390
00391 assert( pChain );
00392 assert( pChain->pNext );
00393
00394
00395 pNodeMin = pChain;
00396 for ( pNode = pChain->pNext; pNode; pNode = pNode->pNext )
00397 if ( pNodeMin->Level > pNode->Level ||
00398 ( pNodeMin->Level == pNode->Level &&
00399 Abc_NodeDroppingCost(pNodeMin) < Abc_NodeDroppingCost(pNode) ) )
00400 pNodeMin = pNode;
00401
00402
00403
00404 pListDir = pListInv = NULL;
00405 for ( pNode = pChain, pNext = pChain->pNext;
00406 pNode;
00407 pNode = pNext, pNext = pNode? pNode->pNext : NULL )
00408 {
00409 if ( pNode == pNodeMin )
00410 continue;
00411
00412 if ( pNodeMin->fPhase == pNode->fPhase )
00413 {
00414 pNode->pNext = pListDir;
00415 pListDir = pNode;
00416 }
00417 else
00418 {
00419 pNode->pNext = pListInv;
00420 pListInv = pNode;
00421 }
00422 }
00423
00424
00425 for ( pNode = pListDir; pNode; pNode = pNode->pNext )
00426 Abc_ObjTransferFanout( pNode, pNodeMin );
00427
00428
00429 if ( pListInv == NULL )
00430 return;
00431
00432
00433 pNodeMinInv = Abc_NtkCreateNodeInv( pNtk, pNodeMin );
00434
00435
00436 for ( pNode = pListInv; pNode; pNode = pNode->pNext )
00437 Abc_ObjTransferFanout( pNode, pNodeMinInv );
00438 }
00439
00440
00452 int Abc_NodeDroppingCost( Abc_Obj_t * pNode )
00453 {
00454 return 1;
00455 }
00456
00457
00458
00459
00460
00472 int Abc_NtkCleanup( Abc_Ntk_t * pNtk, int fVerbose )
00473 {
00474 Vec_Ptr_t * vNodes;
00475 int Counter;
00476 assert( Abc_NtkIsLogic(pNtk) );
00477
00478 vNodes = Abc_NtkDfs( pNtk, 0 );
00479 Counter = Abc_NtkReduceNodes( pNtk, vNodes );
00480 if ( fVerbose )
00481 printf( "Cleanup removed %d dangling nodes.\n", Counter );
00482 Vec_PtrFree( vNodes );
00483 return Counter;
00484 }
00485
00497 int Abc_NtkReduceNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
00498 {
00499 Abc_Obj_t * pNode;
00500 int i, Counter;
00501 assert( Abc_NtkIsLogic(pNtk) );
00502
00503 Vec_PtrForEachEntry( vNodes, pNode, i )
00504 pNode->fMarkA = 1;
00505
00506 Counter = 0;
00507 Abc_NtkForEachNode( pNtk, pNode, i )
00508 if ( pNode->fMarkA == 0 )
00509 {
00510 Abc_NtkDeleteObj( pNode );
00511 Counter++;
00512 }
00513
00514 Vec_PtrForEachEntry( vNodes, pNode, i )
00515 pNode->fMarkA = 0;
00516
00517 if ( !Abc_NtkCheck( pNtk ) )
00518 printf( "Abc_NtkCleanup: The network check has failed.\n" );
00519 return Counter;
00520 }
00521
00522
00523
00524
00536 int Abc_NtkSweep( Abc_Ntk_t * pNtk, int fVerbose )
00537 {
00538 Vec_Ptr_t * vNodes;
00539 Abc_Obj_t * pNode, * pFanout, * pDriver;
00540 int i, nNodesOld;
00541 assert( Abc_NtkIsLogic(pNtk) );
00542
00543 if ( !Abc_NtkToBdd(pNtk) )
00544 {
00545 fprintf( stdout, "Converting to BDD has failed.\n" );
00546 return 1;
00547 }
00548
00549 nNodesOld = Abc_NtkNodeNum(pNtk);
00550 Abc_NtkCleanup( pNtk, 0 );
00551
00552 Abc_NtkRemoveDupFanins(pNtk);
00553 Abc_NtkMinimumBase(pNtk);
00554
00555 vNodes = Vec_PtrAlloc( 100 );
00556 Abc_NtkForEachNode( pNtk, pNode, i )
00557 if ( Abc_ObjFaninNum(pNode) < 2 )
00558 Vec_PtrPush( vNodes, pNode );
00559
00560 while ( Vec_PtrSize(vNodes) > 0 )
00561 {
00562
00563 pNode = Vec_PtrPop(vNodes);
00564 if ( !Abc_ObjIsNode(pNode) )
00565 continue;
00566
00567 pFanout = Abc_NodeFindNonCoFanout(pNode);
00568 if ( pFanout == NULL )
00569 continue;
00570 assert( Abc_ObjIsNode(pFanout) );
00571
00572 if ( Abc_ObjFaninNum(pNode) == 0 )
00573 Abc_NodeConstantInput( pFanout, pNode, Abc_NodeIsConst0(pNode) );
00574 else
00575 {
00576 assert( Abc_ObjFaninNum(pNode) == 1 );
00577 pDriver = Abc_ObjFanin0(pNode);
00578 if ( Abc_NodeIsInv(pNode) )
00579 Abc_NodeComplementInput( pFanout, pNode );
00580 Abc_ObjPatchFanin( pFanout, pNode, pDriver );
00581 }
00582 Abc_NodeRemoveDupFanins( pFanout );
00583 Abc_NodeMinimumBase( pFanout );
00584
00585 if ( Abc_ObjFaninNum(pFanout) < 2 )
00586 Vec_PtrPush( vNodes, pFanout );
00587
00588 if ( Abc_ObjFanoutNum(pNode) > 0 )
00589 Vec_PtrPush( vNodes, pNode );
00590 else
00591 Abc_NtkDeleteObj_rec( pNode, 1 );
00592 }
00593 Vec_PtrFree( vNodes );
00594
00595
00596
00597
00598 Abc_NtkForEachCo( pNtk, pFanout, i )
00599 {
00600 pNode = Abc_ObjFanin0(pFanout);
00601 if ( Abc_ObjFaninNum(pNode) != 1 )
00602 continue;
00603 pDriver = Abc_ObjFanin0(pNode);
00604 if ( !(Abc_ObjFanoutNum(pDriver) == 1 && Abc_ObjIsNode(pDriver)) )
00605 continue;
00606
00607 if ( Abc_NodeIsInv(pNode) )
00608 pDriver->pData = Cudd_Not(pDriver->pData);
00609 Abc_ObjPatchFanin( pFanout, pNode, pDriver );
00610 }
00611
00612 Abc_NtkCleanup( pNtk, 0 );
00613
00614 if ( fVerbose )
00615 printf( "Sweep removed %d nodes.\n", nNodesOld - Abc_NtkNodeNum(pNtk) );
00616 return nNodesOld - Abc_NtkNodeNum(pNtk);
00617 }
00618
00619
00631 void Abc_NodeConstantInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin, bool fConst0 )
00632 {
00633 DdManager * dd = pNode->pNtk->pManFunc;
00634 DdNode * bVar, * bTemp;
00635 int iFanin;
00636 assert( Abc_NtkIsBddLogic(pNode->pNtk) );
00637 if ( (iFanin = Vec_IntFind( &pNode->vFanins, pFanin->Id )) == -1 )
00638 {
00639 printf( "Node %s should be among", Abc_ObjName(pFanin) );
00640 printf( " the fanins of node %s...\n", Abc_ObjName(pNode) );
00641 return;
00642 }
00643 bVar = Cudd_NotCond( Cudd_bddIthVar(dd, iFanin), fConst0 );
00644 pNode->pData = Cudd_Cofactor( dd, bTemp = pNode->pData, bVar ); Cudd_Ref( pNode->pData );
00645 Cudd_RecursiveDeref( dd, bTemp );
00646 }
00647
00659 void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
00660 {
00661 DdManager * dd = pNode->pNtk->pManFunc;
00662 DdNode * bVar, * bCof0, * bCof1;
00663 int iFanin;
00664 assert( Abc_NtkIsBddLogic(pNode->pNtk) );
00665 if ( (iFanin = Vec_IntFind( &pNode->vFanins, pFanin->Id )) == -1 )
00666 {
00667 printf( "Node %s should be among", Abc_ObjName(pFanin) );
00668 printf( " the fanins of node %s...\n", Abc_ObjName(pNode) );
00669 return;
00670 }
00671 bVar = Cudd_bddIthVar( dd, iFanin );
00672 bCof0 = Cudd_Cofactor( dd, pNode->pData, Cudd_Not(bVar) ); Cudd_Ref( bCof0 );
00673 bCof1 = Cudd_Cofactor( dd, pNode->pData, bVar ); Cudd_Ref( bCof1 );
00674 Cudd_RecursiveDeref( dd, pNode->pData );
00675 pNode->pData = Cudd_bddIte( dd, bVar, bCof0, bCof1 ); Cudd_Ref( pNode->pData );
00676 Cudd_RecursiveDeref( dd, bCof0 );
00677 Cudd_RecursiveDeref( dd, bCof1 );
00678 }
00679
00680
00681
00693 int Abc_NodeRemoveNonCurrentObjects( Abc_Ntk_t * pNtk )
00694 {
00695 Abc_Obj_t * pObj;
00696 int Counter, i;
00697 int fVerbose = 0;
00698
00699
00700 if ( fVerbose )
00701 {
00702 printf( "These nodes will be deleted: \n" );
00703 Abc_NtkForEachObj( pNtk, pObj, i )
00704 if ( !Abc_NodeIsTravIdCurrent( pObj ) )
00705 {
00706 printf( " " );
00707 Abc_ObjPrint( stdout, pObj );
00708 }
00709 }
00710
00711
00712 Counter = 0;
00713 Abc_NtkForEachObj( pNtk, pObj, i )
00714 if ( !Abc_NodeIsTravIdCurrent( pObj ) )
00715 {
00716 Abc_NtkDeleteObj( pObj );
00717 Counter++;
00718 }
00719 return Counter;
00720 }
00721
00733 void Abc_NtkSetTravId_rec( Abc_Obj_t * pObj )
00734 {
00735 Abc_NodeSetTravIdCurrent(pObj);
00736 if ( Abc_ObjFaninNum(pObj) == 0 )
00737 return;
00738 assert( Abc_ObjFaninNum(pObj) == 1 );
00739 Abc_NtkSetTravId_rec( Abc_ObjFanin0(pObj) );
00740 }
00741
00753 int Abc_NtkCheckConstant_rec( Abc_Obj_t * pObj )
00754 {
00755 if ( Abc_ObjFaninNum(pObj) == 0 )
00756 {
00757 if ( !Abc_ObjIsNode(pObj) )
00758 return -1;
00759 if ( Abc_NodeIsConst0(pObj) )
00760 return 0;
00761 if ( Abc_NodeIsConst1(pObj) )
00762 return 1;
00763 assert( 0 );
00764 return -1;
00765 }
00766 if ( Abc_ObjIsLatch(pObj) || Abc_ObjFaninNum(pObj) > 1 )
00767 return -1;
00768 if ( !Abc_ObjIsNode(pObj) || Abc_NodeIsBuf(pObj) )
00769 return Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pObj) );
00770 if ( Abc_NodeIsInv(pObj) )
00771 {
00772 int RetValue = Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pObj) );
00773 if ( RetValue == 0 )
00774 return 1;
00775 if ( RetValue == 1 )
00776 return 0;
00777 return RetValue;
00778 }
00779 assert( 0 );
00780 return -1;
00781 }
00782
00797 int Abc_NtkLatchSweep( Abc_Ntk_t * pNtk )
00798 {
00799 Abc_Obj_t * pFanin, * pLatch, * pLatchPivot = NULL;
00800 int Counter, RetValue, i;
00801 Counter = 0;
00802
00803 Abc_NtkForEachLatch( pNtk, pLatch, i )
00804 {
00805
00806 RetValue = Abc_NtkCheckConstant_rec( Abc_ObjFanin0(pLatch) );
00807 if ( RetValue == -1 )
00808 continue;
00809
00810 if ( (RetValue == 1 && Abc_LatchIsInit0(pLatch)) ||
00811 (RetValue == 0 && Abc_LatchIsInit1(pLatch)) )
00812 {
00813
00814 if ( pLatchPivot == NULL )
00815 {
00816 pLatchPivot = pLatch;
00817 continue;
00818 }
00819 if ( Abc_LatchInit(pLatch) != Abc_LatchInit(pLatchPivot) )
00820 pFanin = Abc_NtkCreateNodeInv( pNtk, Abc_ObjFanout0(pLatchPivot) );
00821 else
00822 pFanin = Abc_ObjFanout0(pLatchPivot);
00823 }
00824 else
00825 pFanin = Abc_ObjFanin0(Abc_ObjFanin0(pLatch));
00826
00827 Abc_ObjTransferFanout( Abc_ObjFanout0(pLatch), pFanin );
00828
00829 Abc_NtkDeleteObj_rec( Abc_ObjFanout0(pLatch), 0 );
00830 Counter++;
00831 }
00832 return Counter;
00833 }
00834
00847 int Abc_NtkReplaceAutonomousLogic( Abc_Ntk_t * pNtk )
00848 {
00849 Abc_Obj_t * pNode, * pFanin;
00850 Vec_Ptr_t * vNodes;
00851 int i, k, Counter;
00852
00853 vNodes = Vec_PtrAlloc( 100 );
00854 Abc_NtkForEachObj( pNtk, pNode, i )
00855 {
00856
00857 if ( !Abc_NodeIsTravIdCurrent(pNode) )
00858 continue;
00859
00860 Abc_ObjForEachFanin( pNode, pFanin, k )
00861 {
00862
00863 if ( Abc_NodeIsTravIdCurrent(pFanin) )
00864 continue;
00865
00866 if ( Abc_NtkCheckConstant_rec(pFanin) != -1 ||
00867 (Abc_ObjIsBo(pFanin) && Abc_NtkCheckConstant_rec(Abc_ObjFanin0(Abc_ObjFanin0(pFanin))) != -1) )
00868 {
00869 Abc_NtkSetTravId_rec( pFanin );
00870 continue;
00871 }
00872 assert( !Abc_ObjIsLatch(pFanin) );
00873 Vec_PtrPush( vNodes, pFanin );
00874 }
00875 }
00876 Vec_PtrUniqify( vNodes, Abc_ObjPointerCompare );
00877
00878 Vec_PtrForEachEntry( vNodes, pNode, i )
00879 {
00880 pFanin = Abc_NtkCreatePi(pNtk);
00881 Abc_ObjAssignName( pFanin, Abc_ObjName(pFanin), NULL );
00882 Abc_NodeSetTravIdCurrent( pFanin );
00883 Abc_ObjTransferFanout( pNode, pFanin );
00884 }
00885 Counter = Vec_PtrSize(vNodes);
00886 Vec_PtrFree( vNodes );
00887 return Counter;
00888 }
00889
00904 int Abc_NtkCleanupSeq( Abc_Ntk_t * pNtk, int fLatchSweep, int fAutoSweep, int fVerbose )
00905 {
00906 Vec_Ptr_t * vNodes;
00907 int Counter;
00908 assert( Abc_NtkIsLogic(pNtk) );
00909
00910 vNodes = Abc_NtkDfsSeq( pNtk );
00911 Vec_PtrFree( vNodes );
00912
00913 Counter = Abc_NodeRemoveNonCurrentObjects( pNtk );
00914 if ( fVerbose )
00915 printf( "Cleanup removed %4d dangling objects.\n", Counter );
00916
00917 if ( fLatchSweep )
00918 {
00919 Counter = Abc_NtkLatchSweep( pNtk );
00920 if ( fVerbose )
00921 printf( "Cleanup removed %4d redundant latches.\n", Counter );
00922 }
00923
00924 if ( fAutoSweep )
00925 {
00926 vNodes = Abc_NtkDfsSeqReverse( pNtk );
00927 Vec_PtrFree( vNodes );
00928
00929 Counter = Abc_NtkReplaceAutonomousLogic( pNtk );
00930 if ( fVerbose )
00931 printf( "Cleanup added %4d additional PIs.\n", Counter );
00932
00933 Counter = Abc_NodeRemoveNonCurrentObjects( pNtk );
00934 if ( fVerbose )
00935 printf( "Cleanup removed %4d autonomous objects.\n", Counter );
00936 }
00937
00938 if ( !Abc_NtkCheck( pNtk ) )
00939 printf( "Abc_NtkCleanupSeq: The network check has failed.\n" );
00940 return 1;
00941 }
00942
00943
00947
00948