00001
00021 #include "abc.h"
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00048
00049
00050 struct Abc_Aig_t_
00051 {
00052 Abc_Ntk_t * pNtkAig;
00053 Abc_Obj_t * pConst1;
00054 Abc_Obj_t ** pBins;
00055 int nBins;
00056 int nEntries;
00057 Vec_Ptr_t * vNodes;
00058 Vec_Ptr_t * vStackReplaceOld;
00059 Vec_Ptr_t * vStackReplaceNew;
00060 Vec_Vec_t * vLevels;
00061 Vec_Vec_t * vLevelsR;
00062 Vec_Ptr_t * vAddedCells;
00063 Vec_Ptr_t * vUpdatedNets;
00064
00065 int nStrash0;
00066 int nStrash1;
00067 int nStrash5;
00068 int nStrash2;
00069 };
00070
00071
00072 #define Abc_AigBinForEachEntry( pBin, pEnt ) \
00073 for ( pEnt = pBin; \
00074 pEnt; \
00075 pEnt = pEnt->pNext )
00076 #define Abc_AigBinForEachEntrySafe( pBin, pEnt, pEnt2 ) \
00077 for ( pEnt = pBin, \
00078 pEnt2 = pEnt? pEnt->pNext: NULL; \
00079 pEnt; \
00080 pEnt = pEnt2, \
00081 pEnt2 = pEnt? pEnt->pNext: NULL )
00082
00083
00084
00085
00086
00087
00088 static unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize )
00089 {
00090 unsigned Key = 0;
00091 Key ^= Abc_ObjRegular(p0)->Id * 7937;
00092 Key ^= Abc_ObjRegular(p1)->Id * 2971;
00093 Key ^= Abc_ObjIsComplement(p0) * 911;
00094 Key ^= Abc_ObjIsComplement(p1) * 353;
00095 return Key % TableSize;
00096 }
00097
00098
00099 static Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 );
00100 static Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, Abc_Obj_t * pAnd );
00101 static void Abc_AigAndDelete( Abc_Aig_t * pMan, Abc_Obj_t * pThis );
00102 static void Abc_AigResize( Abc_Aig_t * pMan );
00103
00104 static void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel );
00105 static void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan );
00106 static void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan );
00107 static void Abc_AigRemoveFromLevelStructure( Vec_Vec_t * vStruct, Abc_Obj_t * pNode );
00108 static void Abc_AigRemoveFromLevelStructureR( Vec_Vec_t * vStruct, Abc_Obj_t * pNode );
00109
00113
00125 Abc_Aig_t * Abc_AigAlloc( Abc_Ntk_t * pNtkAig )
00126 {
00127 Abc_Aig_t * pMan;
00128
00129 pMan = ALLOC( Abc_Aig_t, 1 );
00130 memset( pMan, 0, sizeof(Abc_Aig_t) );
00131
00132 pMan->nBins = Cudd_PrimeCopy( 10000 );
00133 pMan->pBins = ALLOC( Abc_Obj_t *, pMan->nBins );
00134 memset( pMan->pBins, 0, sizeof(Abc_Obj_t *) * pMan->nBins );
00135 pMan->vNodes = Vec_PtrAlloc( 100 );
00136 pMan->vLevels = Vec_VecAlloc( 100 );
00137 pMan->vLevelsR = Vec_VecAlloc( 100 );
00138 pMan->vStackReplaceOld = Vec_PtrAlloc( 100 );
00139 pMan->vStackReplaceNew = Vec_PtrAlloc( 100 );
00140
00141 assert( pNtkAig->vObjs->nSize == 0 );
00142 pMan->pConst1 = Abc_NtkCreateObj( pNtkAig, ABC_OBJ_NODE );
00143 pMan->pConst1->Type = ABC_OBJ_CONST1;
00144 pMan->pConst1->fPhase = 1;
00145 pNtkAig->nObjCounts[ABC_OBJ_NODE]--;
00146
00147 pMan->pNtkAig = pNtkAig;
00148 return pMan;
00149 }
00150
00162 void Abc_AigFree( Abc_Aig_t * pMan )
00163 {
00164 assert( Vec_PtrSize( pMan->vStackReplaceOld ) == 0 );
00165 assert( Vec_PtrSize( pMan->vStackReplaceNew ) == 0 );
00166
00167 if ( pMan->vAddedCells )
00168 Vec_PtrFree( pMan->vAddedCells );
00169 if ( pMan->vUpdatedNets )
00170 Vec_PtrFree( pMan->vUpdatedNets );
00171 Vec_VecFree( pMan->vLevels );
00172 Vec_VecFree( pMan->vLevelsR );
00173 Vec_PtrFree( pMan->vStackReplaceOld );
00174 Vec_PtrFree( pMan->vStackReplaceNew );
00175 Vec_PtrFree( pMan->vNodes );
00176 free( pMan->pBins );
00177 free( pMan );
00178 }
00179
00191 int Abc_AigCleanup( Abc_Aig_t * pMan )
00192 {
00193 Vec_Ptr_t * vDangles;
00194 Abc_Obj_t * pAnd;
00195 int i, nNodesOld;
00196
00197
00198 nNodesOld = pMan->nEntries;
00199
00200 vDangles = Vec_PtrAlloc( 100 );
00201 for ( i = 0; i < pMan->nBins; i++ )
00202 Abc_AigBinForEachEntry( pMan->pBins[i], pAnd )
00203 if ( Abc_ObjFanoutNum(pAnd) == 0 )
00204 Vec_PtrPush( vDangles, pAnd );
00205
00206 Vec_PtrForEachEntry( vDangles, pAnd, i )
00207 Abc_AigDeleteNode( pMan, pAnd );
00208 Vec_PtrFree( vDangles );
00209 return nNodesOld - pMan->nEntries;
00210 }
00211
00223 bool Abc_AigCheck( Abc_Aig_t * pMan )
00224 {
00225 Abc_Obj_t * pObj, * pAnd;
00226 int i, nFanins, Counter;
00227 Abc_NtkForEachNode( pMan->pNtkAig, pObj, i )
00228 {
00229 nFanins = Abc_ObjFaninNum(pObj);
00230 if ( nFanins == 0 )
00231 {
00232 if ( !Abc_AigNodeIsConst(pObj) )
00233 {
00234 printf( "Abc_AigCheck: The AIG has non-standard constant nodes.\n" );
00235 return 0;
00236 }
00237 continue;
00238 }
00239 if ( nFanins == 1 )
00240 {
00241 printf( "Abc_AigCheck: The AIG has single input nodes.\n" );
00242 return 0;
00243 }
00244 if ( nFanins > 2 )
00245 {
00246 printf( "Abc_AigCheck: The AIG has non-standard nodes.\n" );
00247 return 0;
00248 }
00249 if ( pObj->Level != 1 + ABC_MAX( Abc_ObjFanin0(pObj)->Level, Abc_ObjFanin1(pObj)->Level ) )
00250 printf( "Abc_AigCheck: Node \"%s\" has level that does not agree with the fanin levels.\n", Abc_ObjName(pObj) );
00251 pAnd = Abc_AigAndLookup( pMan, Abc_ObjChild0(pObj), Abc_ObjChild1(pObj) );
00252 if ( pAnd != pObj )
00253 printf( "Abc_AigCheck: Node \"%s\" is not in the structural hashing table.\n", Abc_ObjName(pObj) );
00254 }
00255
00256 Counter = 0;
00257 for ( i = 0; i < pMan->nBins; i++ )
00258 Abc_AigBinForEachEntry( pMan->pBins[i], pAnd )
00259 Counter++;
00260 if ( Counter != Abc_NtkNodeNum(pMan->pNtkAig) )
00261 {
00262 printf( "Abc_AigCheck: The number of nodes in the structural hashing table is wrong.\n" );
00263 return 0;
00264 }
00265
00266 Abc_NtkForEachNode( pMan->pNtkAig, pObj, i )
00267 if ( Abc_AigNodeIsChoice(pObj) )
00268 for ( pAnd = pObj->pData; pAnd; pAnd = pAnd->pData )
00269 if ( Abc_ObjFanoutNum(pAnd) > 0 )
00270 {
00271 printf( "Abc_AigCheck: Representative %s", Abc_ObjName(pAnd) );
00272 printf( " of choice node %s has %d fanouts.\n", Abc_ObjName(pObj), Abc_ObjFanoutNum(pAnd) );
00273 return 0;
00274 }
00275 return 1;
00276 }
00277
00289 int Abc_AigLevel( Abc_Ntk_t * pNtk )
00290 {
00291 Abc_Obj_t * pNode;
00292 int i, LevelsMax;
00293 assert( Abc_NtkIsStrash(pNtk) );
00294
00295 LevelsMax = 0;
00296 Abc_NtkForEachCo( pNtk, pNode, i )
00297 if ( LevelsMax < (int)Abc_ObjFanin0(pNode)->Level )
00298 LevelsMax = (int)Abc_ObjFanin0(pNode)->Level;
00299 return LevelsMax;
00300 }
00301
00302
00314 Abc_Obj_t * Abc_AigAndCreate( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
00315 {
00316 Abc_Obj_t * pAnd;
00317 unsigned Key;
00318
00319 if ( pMan->nEntries > 2 * pMan->nBins )
00320 Abc_AigResize( pMan );
00321
00322 if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id )
00323 pAnd = p0, p0 = p1, p1 = pAnd;
00324
00325 pAnd = Abc_NtkCreateNode( pMan->pNtkAig );
00326 Abc_ObjAddFanin( pAnd, p0 );
00327 Abc_ObjAddFanin( pAnd, p1 );
00328
00329 pAnd->Level = 1 + ABC_MAX( Abc_ObjRegular(p0)->Level, Abc_ObjRegular(p1)->Level );
00330 pAnd->fExor = Abc_NodeIsExorType(pAnd);
00331 pAnd->fPhase = (Abc_ObjIsComplement(p0) ^ Abc_ObjRegular(p0)->fPhase) & (Abc_ObjIsComplement(p1) ^ Abc_ObjRegular(p1)->fPhase);
00332
00333 Key = Abc_HashKey2( p0, p1, pMan->nBins );
00334 pAnd->pNext = pMan->pBins[Key];
00335 pMan->pBins[Key] = pAnd;
00336 pMan->nEntries++;
00337
00338
00339
00340 pAnd->pCopy = NULL;
00341
00342 if ( pMan->vAddedCells )
00343 Vec_PtrPush( pMan->vAddedCells, pAnd );
00344
00345 if ( pAnd->pNtk->pHaig )
00346 pAnd->pEquiv = Hop_And( pAnd->pNtk->pHaig, Abc_ObjChild0Equiv(pAnd), Abc_ObjChild1Equiv(pAnd) );
00347 return pAnd;
00348 }
00349
00361 Abc_Obj_t * Abc_AigAndCreateFrom( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, Abc_Obj_t * pAnd )
00362 {
00363 Abc_Obj_t * pTemp;
00364 unsigned Key;
00365 assert( !Abc_ObjIsComplement(pAnd) );
00366
00367 if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id )
00368 pTemp = p0, p0 = p1, p1 = pTemp;
00369
00370 Abc_ObjAddFanin( pAnd, p0 );
00371 Abc_ObjAddFanin( pAnd, p1 );
00372
00373 pAnd->Level = 1 + ABC_MAX( Abc_ObjRegular(p0)->Level, Abc_ObjRegular(p1)->Level );
00374 pAnd->fExor = Abc_NodeIsExorType(pAnd);
00375
00376 Key = Abc_HashKey2( p0, p1, pMan->nBins );
00377 pAnd->pNext = pMan->pBins[Key];
00378 pMan->pBins[Key] = pAnd;
00379 pMan->nEntries++;
00380
00381
00382
00383 pAnd->pCopy = NULL;
00384
00385
00386
00387
00388 if ( pAnd->pNtk->pHaig )
00389 pAnd->pEquiv = Hop_And( pAnd->pNtk->pHaig, Abc_ObjChild0Equiv(pAnd), Abc_ObjChild1Equiv(pAnd) );
00390 return pAnd;
00391 }
00392
00404 Abc_Obj_t * Abc_AigAndLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
00405 {
00406 Abc_Obj_t * pAnd, * pConst1;
00407 unsigned Key;
00408 assert( Abc_ObjRegular(p0)->pNtk->pManFunc == pMan );
00409 assert( Abc_ObjRegular(p1)->pNtk->pManFunc == pMan );
00410
00411 pConst1 = Abc_AigConst1(pMan->pNtkAig);
00412 if ( p0 == p1 )
00413 return p0;
00414 if ( p0 == Abc_ObjNot(p1) )
00415 return Abc_ObjNot(pConst1);
00416 if ( Abc_ObjRegular(p0) == pConst1 )
00417 {
00418 if ( p0 == pConst1 )
00419 return p1;
00420 return Abc_ObjNot(pConst1);
00421 }
00422 if ( Abc_ObjRegular(p1) == pConst1 )
00423 {
00424 if ( p1 == pConst1 )
00425 return p0;
00426 return Abc_ObjNot(pConst1);
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 {
00443 int nFans0 = Abc_ObjFanoutNum( Abc_ObjRegular(p0) );
00444 int nFans1 = Abc_ObjFanoutNum( Abc_ObjRegular(p1) );
00445 if ( nFans0 == 0 || nFans1 == 0 )
00446 return NULL;
00447 }
00448
00449
00450 if ( Abc_ObjRegular(p0)->Id > Abc_ObjRegular(p1)->Id )
00451 pAnd = p0, p0 = p1, p1 = pAnd;
00452
00453 Key = Abc_HashKey2( p0, p1, pMan->nBins );
00454
00455 Abc_AigBinForEachEntry( pMan->pBins[Key], pAnd )
00456 if ( p0 == Abc_ObjChild0(pAnd) && p1 == Abc_ObjChild1(pAnd) )
00457 {
00458
00459 return pAnd;
00460 }
00461 return NULL;
00462 }
00463
00475 Abc_Obj_t * Abc_AigXorLookup( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1, int * pType )
00476 {
00477 Abc_Obj_t * pNode1, * pNode2, * pNode;
00478
00479 if ( pType ) *pType = 0;
00480
00481 if ( (pNode1 = Abc_AigAndLookup(pMan, Abc_ObjNot(p0), Abc_ObjNot(p1))) &&
00482 (pNode2 = Abc_AigAndLookup(pMan, p0, p1)) )
00483 {
00484 pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00485 if ( pNode && pType ) *pType = 1;
00486 return pNode;
00487 }
00488
00489 if ( (pNode1 = Abc_AigAndLookup(pMan, p0, Abc_ObjNot(p1))) &&
00490 (pNode2 = Abc_AigAndLookup(pMan, Abc_ObjNot(p0), p1)) )
00491 {
00492 pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00493 return pNode? Abc_ObjNot(pNode) : NULL;
00494 }
00495 return NULL;
00496 }
00497
00509 Abc_Obj_t * Abc_AigMuxLookup( Abc_Aig_t * pMan, Abc_Obj_t * pC, Abc_Obj_t * pT, Abc_Obj_t * pE, int * pType )
00510 {
00511 Abc_Obj_t * pNode1, * pNode2, * pNode;
00512
00513 if ( pType ) *pType = 0;
00514
00515 if ( (pNode1 = Abc_AigAndLookup(pMan, pC, Abc_ObjNot(pT))) &&
00516 (pNode2 = Abc_AigAndLookup(pMan, Abc_ObjNot(pC), Abc_ObjNot(pE))) )
00517 {
00518 pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00519 if ( pNode && pType ) *pType = 1;
00520 return pNode;
00521 }
00522
00523 if ( (pNode1 = Abc_AigAndLookup(pMan, pC, pT)) &&
00524 (pNode2 = Abc_AigAndLookup(pMan, Abc_ObjNot(pC), pE)) )
00525 {
00526 pNode = Abc_AigAndLookup( pMan, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00527 return pNode? Abc_ObjNot(pNode) : NULL;
00528 }
00529 return NULL;
00530 }
00531
00543 void Abc_AigAndDelete( Abc_Aig_t * pMan, Abc_Obj_t * pThis )
00544 {
00545 Abc_Obj_t * pAnd, * pAnd0, * pAnd1, ** ppPlace;
00546 unsigned Key;
00547 assert( !Abc_ObjIsComplement(pThis) );
00548 assert( Abc_ObjIsNode(pThis) );
00549 assert( Abc_ObjFaninNum(pThis) == 2 );
00550 assert( pMan->pNtkAig == pThis->pNtk );
00551
00552 pAnd0 = Abc_ObjRegular( Abc_ObjChild0(pThis) );
00553 pAnd1 = Abc_ObjRegular( Abc_ObjChild1(pThis) );
00554 Key = Abc_HashKey2( Abc_ObjChild0(pThis), Abc_ObjChild1(pThis), pMan->nBins );
00555
00556 ppPlace = pMan->pBins + Key;
00557 Abc_AigBinForEachEntry( pMan->pBins[Key], pAnd )
00558 {
00559 if ( pAnd != pThis )
00560 {
00561 ppPlace = &pAnd->pNext;
00562 continue;
00563 }
00564 *ppPlace = pAnd->pNext;
00565 break;
00566 }
00567 assert( pAnd == pThis );
00568 pMan->nEntries--;
00569
00570 if ( pThis->pNtk->pManCut )
00571 Abc_NodeFreeCuts( pThis->pNtk->pManCut, pThis );
00572 }
00573
00585 void Abc_AigResize( Abc_Aig_t * pMan )
00586 {
00587 Abc_Obj_t ** pBinsNew;
00588 Abc_Obj_t * pEnt, * pEnt2;
00589 int nBinsNew, Counter, i, clk;
00590 unsigned Key;
00591
00592 clk = clock();
00593
00594 nBinsNew = Cudd_PrimeCopy( 3 * pMan->nBins );
00595
00596 pBinsNew = ALLOC( Abc_Obj_t *, nBinsNew );
00597 memset( pBinsNew, 0, sizeof(Abc_Obj_t *) * nBinsNew );
00598
00599 Counter = 0;
00600 for ( i = 0; i < pMan->nBins; i++ )
00601 Abc_AigBinForEachEntrySafe( pMan->pBins[i], pEnt, pEnt2 )
00602 {
00603 Key = Abc_HashKey2( Abc_ObjChild0(pEnt), Abc_ObjChild1(pEnt), nBinsNew );
00604 pEnt->pNext = pBinsNew[Key];
00605 pBinsNew[Key] = pEnt;
00606 Counter++;
00607 }
00608 assert( Counter == pMan->nEntries );
00609
00610
00611
00612 free( pMan->pBins );
00613 pMan->pBins = pBinsNew;
00614 pMan->nBins = nBinsNew;
00615 }
00616
00628 void Abc_AigRehash( Abc_Aig_t * pMan )
00629 {
00630 Abc_Obj_t ** pBinsNew;
00631 Abc_Obj_t * pEnt, * pEnt2;
00632 int * pArray;
00633 unsigned Key;
00634 int Counter, Temp, i;
00635
00636
00637 pBinsNew = ALLOC( Abc_Obj_t *, pMan->nBins );
00638 memset( pBinsNew, 0, sizeof(Abc_Obj_t *) * pMan->nBins );
00639
00640 Counter = 0;
00641 for ( i = 0; i < pMan->nBins; i++ )
00642 Abc_AigBinForEachEntrySafe( pMan->pBins[i], pEnt, pEnt2 )
00643 {
00644
00645 pArray = pEnt->vFanins.pArray;
00646 if ( pArray[0] > pArray[1] )
00647 {
00648 Temp = pArray[0];
00649 pArray[0] = pArray[1];
00650 pArray[1] = Temp;
00651 Temp = pEnt->fCompl0;
00652 pEnt->fCompl0 = pEnt->fCompl1;
00653 pEnt->fCompl1 = Temp;
00654 }
00655
00656 Key = Abc_HashKey2( Abc_ObjChild0(pEnt), Abc_ObjChild1(pEnt), pMan->nBins );
00657 pEnt->pNext = pBinsNew[Key];
00658 pBinsNew[Key] = pEnt;
00659 Counter++;
00660 }
00661 assert( Counter == pMan->nEntries );
00662
00663 free( pMan->pBins );
00664 pMan->pBins = pBinsNew;
00665 }
00666
00667
00668
00669
00670
00671
00683 Abc_Obj_t * Abc_AigConst1( Abc_Ntk_t * pNtk )
00684 {
00685 assert( Abc_NtkIsStrash(pNtk) );
00686 return ((Abc_Aig_t *)pNtk->pManFunc)->pConst1;
00687 }
00688
00700 Abc_Obj_t * Abc_AigAnd( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
00701 {
00702 Abc_Obj_t * pAnd;
00703 if ( (pAnd = Abc_AigAndLookup( pMan, p0, p1 )) )
00704 return pAnd;
00705 return Abc_AigAndCreate( pMan, p0, p1 );
00706 }
00707
00719 Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
00720 {
00721 return Abc_ObjNot( Abc_AigAnd( pMan, Abc_ObjNot(p0), Abc_ObjNot(p1) ) );
00722 }
00723
00735 Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 )
00736 {
00737 return Abc_AigOr( pMan, Abc_AigAnd(pMan, p0, Abc_ObjNot(p1)),
00738 Abc_AigAnd(pMan, p1, Abc_ObjNot(p0)) );
00739 }
00740
00752 Abc_Obj_t * Abc_AigMiter_rec( Abc_Aig_t * pMan, Abc_Obj_t ** ppObjs, int nObjs )
00753 {
00754 Abc_Obj_t * pObj1, * pObj2;
00755 if ( nObjs == 1 )
00756 return ppObjs[0];
00757 pObj1 = Abc_AigMiter_rec( pMan, ppObjs, nObjs/2 );
00758 pObj2 = Abc_AigMiter_rec( pMan, ppObjs + nObjs/2, nObjs - nObjs/2 );
00759 return Abc_AigOr( pMan, pObj1, pObj2 );
00760 }
00761
00773 Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
00774 {
00775 int i;
00776 if ( vPairs->nSize == 0 )
00777 return Abc_ObjNot( Abc_AigConst1(pMan->pNtkAig) );
00778 assert( vPairs->nSize % 2 == 0 );
00779
00780 for ( i = 0; i < vPairs->nSize; i += 2 )
00781 vPairs->pArray[i/2] = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] );
00782 vPairs->nSize = vPairs->nSize/2;
00783 return Abc_AigMiter_rec( pMan, (Abc_Obj_t **)vPairs->pArray, vPairs->nSize );
00784 }
00785
00797 Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs )
00798 {
00799 Abc_Obj_t * pMiter, * pXor;
00800 int i;
00801 assert( vPairs->nSize % 2 == 0 );
00802
00803 pMiter = Abc_ObjNot( Abc_AigConst1(pMan->pNtkAig) );
00804 for ( i = 0; i < vPairs->nSize; i += 2 )
00805 {
00806 pXor = Abc_AigXor( pMan, vPairs->pArray[i], vPairs->pArray[i+1] );
00807 pMiter = Abc_AigOr( pMan, pMiter, pXor );
00808 }
00809 return pMiter;
00810 }
00811
00812
00813
00814
00826 void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, bool fUpdateLevel )
00827 {
00828 assert( Vec_PtrSize(pMan->vStackReplaceOld) == 0 );
00829 assert( Vec_PtrSize(pMan->vStackReplaceNew) == 0 );
00830 Vec_PtrPush( pMan->vStackReplaceOld, pOld );
00831 Vec_PtrPush( pMan->vStackReplaceNew, pNew );
00832 assert( !Abc_ObjIsComplement(pOld) );
00833
00834 if ( pOld->pNtk->pHaig )
00835 Hop_ObjCreateChoice( pOld->pEquiv, Abc_ObjRegular(pNew)->pEquiv );
00836
00837 while ( Vec_PtrSize(pMan->vStackReplaceOld) )
00838 {
00839 pOld = Vec_PtrPop( pMan->vStackReplaceOld );
00840 pNew = Vec_PtrPop( pMan->vStackReplaceNew );
00841 Abc_AigReplace_int( pMan, pOld, pNew, fUpdateLevel );
00842 }
00843 if ( fUpdateLevel )
00844 {
00845 Abc_AigUpdateLevel_int( pMan );
00846 if ( pMan->pNtkAig->vLevelsR )
00847 Abc_AigUpdateLevelR_int( pMan );
00848 }
00849 }
00850
00862 void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel )
00863 {
00864 Abc_Obj_t * pFanin1, * pFanin2, * pFanout, * pFanoutNew, * pFanoutFanout;
00865 int k, v, iFanin;
00866
00867
00868 assert( !Abc_ObjIsComplement(pOld) );
00869 assert( Abc_ObjFanoutNum(pOld) > 0 );
00870
00871 Abc_NodeCollectFanouts( pOld, pMan->vNodes );
00872 Vec_PtrForEachEntry( pMan->vNodes, pFanout, k )
00873 {
00874 if ( Abc_ObjIsCo(pFanout) )
00875 {
00876 Abc_ObjPatchFanin( pFanout, pOld, pNew );
00877 continue;
00878 }
00879
00880 iFanin = Vec_IntFind( &pFanout->vFanins, pOld->Id );
00881 assert( iFanin == 0 || iFanin == 1 );
00882
00883 pFanin1 = Abc_ObjNotCond( pNew, Abc_ObjFaninC(pFanout, iFanin) );
00884 assert( Abc_ObjRegular(pFanin1) != pFanout );
00885
00886 pFanin2 = Abc_ObjChild( pFanout, iFanin ^ 1 );
00887 assert( Abc_ObjRegular(pFanin2) != pFanout );
00888
00889 if ( (pFanoutNew = Abc_AigAndLookup( pMan, pFanin1, pFanin2 )) )
00890 {
00891
00892 Vec_PtrPush( pMan->vStackReplaceOld, pFanout );
00893 Vec_PtrPush( pMan->vStackReplaceNew, pFanoutNew );
00894 continue;
00895 }
00896
00897
00898 assert( Abc_ObjRegular(pFanin1) != Abc_ObjRegular(pFanin2) );
00899
00900
00901 if ( pFanout->fMarkA )
00902 Abc_AigRemoveFromLevelStructure( pMan->vLevels, pFanout );
00903
00904 if ( pFanout->fMarkB )
00905 Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pFanout );
00906
00907
00908 Abc_AigAndDelete( pMan, pFanout );
00909
00910 Abc_ObjRemoveFanins( pFanout );
00911
00912 Abc_AigAndCreateFrom( pMan, pFanin1, pFanin2, pFanout );
00913 assert( Abc_AigNodeIsAcyclic(pFanout, pFanout) );
00914
00915 if ( fUpdateLevel )
00916 {
00917
00918 assert( pFanout->fMarkA == 0 );
00919 pFanout->fMarkA = 1;
00920 Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
00921
00922 if ( pMan->pNtkAig->vLevelsR )
00923 {
00924 assert( pFanout->fMarkB == 0 );
00925 pFanout->fMarkB = 1;
00926 Vec_VecPush( pMan->vLevelsR, Abc_ObjReverseLevel(pFanout), pFanout );
00927 }
00928 }
00929
00930
00931 Abc_ObjForEachFanout( pFanout, pFanoutFanout, v )
00932 if ( Abc_AigNodeIsAnd(pFanoutFanout) )
00933 pFanoutFanout->fExor = Abc_NodeIsExorType(pFanoutFanout);
00934 }
00935
00936 if ( Abc_ObjFanoutNum(pOld) == 0 )
00937 Abc_AigDeleteNode( pMan, pOld );
00938 }
00939
00951 void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pNode )
00952 {
00953 Abc_Obj_t * pNode0, * pNode1, * pTemp;
00954 int i, k;
00955
00956
00957 assert( !Abc_ObjIsComplement(pNode) );
00958 assert( Abc_ObjIsNode(pNode) );
00959 assert( Abc_ObjFaninNum(pNode) == 2 );
00960 assert( Abc_ObjFanoutNum(pNode) == 0 );
00961
00962
00963 Vec_PtrForEachEntry( pMan->vStackReplaceOld, pTemp, i )
00964 if ( pNode == pTemp )
00965 {
00966
00967 for ( k = i; k < pMan->vStackReplaceOld->nSize - 1; k++ )
00968 {
00969 pMan->vStackReplaceOld->pArray[k] = pMan->vStackReplaceOld->pArray[k+1];
00970 pMan->vStackReplaceNew->pArray[k] = pMan->vStackReplaceNew->pArray[k+1];
00971 }
00972 pMan->vStackReplaceOld->nSize--;
00973 pMan->vStackReplaceNew->nSize--;
00974 }
00975
00976
00977 Vec_PtrForEachEntry( pMan->vStackReplaceNew, pTemp, i )
00978 if ( pNode == Abc_ObjRegular(pTemp) )
00979 return;
00980
00981
00982 pNode0 = Abc_ObjFanin0( pNode );
00983 pNode1 = Abc_ObjFanin1( pNode );
00984
00985
00986 if ( pMan->vUpdatedNets )
00987 {
00988 Vec_PtrPushUnique( pMan->vUpdatedNets, pNode0 );
00989 Vec_PtrPushUnique( pMan->vUpdatedNets, pNode1 );
00990 }
00991
00992
00993 Abc_AigAndDelete( pMan, pNode );
00994
00995 if ( pNode->fMarkA )
00996 Abc_AigRemoveFromLevelStructure( pMan->vLevels, pNode );
00997 if ( pNode->fMarkB )
00998 Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pNode );
00999
01000 Abc_NtkDeleteObj( pNode );
01001
01002
01003 if ( Abc_ObjIsNode(pNode0) && pNode0->vFanouts.nSize == 0 )
01004 Abc_AigDeleteNode( pMan, pNode0 );
01005 if ( Abc_ObjIsNode(pNode1) && pNode1->vFanouts.nSize == 0 )
01006 Abc_AigDeleteNode( pMan, pNode1 );
01007 }
01008
01009
01025 void Abc_AigUpdateLevel_int( Abc_Aig_t * pMan )
01026 {
01027 Abc_Obj_t * pNode, * pFanout;
01028 Vec_Ptr_t * vVec;
01029 int LevelNew, i, k, v;
01030
01031
01032 Vec_VecForEachLevel( pMan->vLevels, vVec, i )
01033 {
01034 if ( Vec_PtrSize(vVec) == 0 )
01035 continue;
01036 Vec_PtrForEachEntry( vVec, pNode, k )
01037 {
01038 if ( pNode == NULL )
01039 continue;
01040 assert( Abc_ObjIsNode(pNode) );
01041 assert( (int)pNode->Level == i );
01042
01043 assert( pNode->fMarkA == 1 );
01044 pNode->fMarkA = 0;
01045
01046 Abc_ObjForEachFanout( pNode, pFanout, v )
01047 {
01048 if ( Abc_ObjIsCo(pFanout) )
01049 continue;
01050
01051 LevelNew = 1 + ABC_MAX( Abc_ObjFanin0(pFanout)->Level, Abc_ObjFanin1(pFanout)->Level );
01052 assert( LevelNew > i );
01053 if ( (int)pFanout->Level == LevelNew )
01054 continue;
01055
01056 if ( pFanout->fMarkA )
01057 Abc_AigRemoveFromLevelStructure( pMan->vLevels, pFanout );
01058
01059 pFanout->Level = LevelNew;
01060
01061 assert( pFanout->fMarkA == 0 );
01062 pFanout->fMarkA = 1;
01063 Vec_VecPush( pMan->vLevels, pFanout->Level, pFanout );
01064 }
01065 }
01066 Vec_PtrClear( vVec );
01067 }
01068 }
01069
01081 void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan )
01082 {
01083 Abc_Obj_t * pNode, * pFanin, * pFanout;
01084 Vec_Ptr_t * vVec;
01085 int LevelNew, i, k, v, j;
01086
01087
01088 Vec_VecForEachLevel( pMan->vLevelsR, vVec, i )
01089 {
01090 if ( Vec_PtrSize(vVec) == 0 )
01091 continue;
01092 Vec_PtrForEachEntry( vVec, pNode, k )
01093 {
01094 if ( pNode == NULL )
01095 continue;
01096 assert( Abc_ObjIsNode(pNode) );
01097 assert( Abc_ObjReverseLevel(pNode) == i );
01098
01099 assert( pNode->fMarkB == 1 );
01100 pNode->fMarkB = 0;
01101
01102 Abc_ObjForEachFanin( pNode, pFanin, v )
01103 {
01104 if ( Abc_ObjIsCi(pFanin) )
01105 continue;
01106
01107 LevelNew = 0;
01108 Abc_ObjForEachFanout( pFanin, pFanout, j )
01109 if ( LevelNew < Abc_ObjReverseLevel(pFanout) )
01110 LevelNew = Abc_ObjReverseLevel(pFanout);
01111 LevelNew += 1;
01112 assert( LevelNew > i );
01113 if ( Abc_ObjReverseLevel(pFanin) == LevelNew )
01114 continue;
01115
01116 if ( pFanin->fMarkB )
01117 Abc_AigRemoveFromLevelStructureR( pMan->vLevelsR, pFanin );
01118
01119 Abc_ObjSetReverseLevel( pFanin, LevelNew );
01120
01121 assert( pFanin->fMarkB == 0 );
01122 pFanin->fMarkB = 1;
01123 Vec_VecPush( pMan->vLevelsR, LevelNew, pFanin );
01124 }
01125 }
01126 Vec_PtrClear( vVec );
01127 }
01128 }
01129
01141 void Abc_AigRemoveFromLevelStructure( Vec_Vec_t * vStruct, Abc_Obj_t * pNode )
01142 {
01143 Vec_Ptr_t * vVecTemp;
01144 Abc_Obj_t * pTemp;
01145 int m;
01146 assert( pNode->fMarkA );
01147 vVecTemp = Vec_VecEntry( vStruct, pNode->Level );
01148 Vec_PtrForEachEntry( vVecTemp, pTemp, m )
01149 {
01150 if ( pTemp != pNode )
01151 continue;
01152 Vec_PtrWriteEntry( vVecTemp, m, NULL );
01153 break;
01154 }
01155 assert( m < Vec_PtrSize(vVecTemp) );
01156 pNode->fMarkA = 0;
01157 }
01158
01170 void Abc_AigRemoveFromLevelStructureR( Vec_Vec_t * vStruct, Abc_Obj_t * pNode )
01171 {
01172 Vec_Ptr_t * vVecTemp;
01173 Abc_Obj_t * pTemp;
01174 int m;
01175 assert( pNode->fMarkB );
01176 vVecTemp = Vec_VecEntry( vStruct, Abc_ObjReverseLevel(pNode) );
01177 Vec_PtrForEachEntry( vVecTemp, pTemp, m )
01178 {
01179 if ( pTemp != pNode )
01180 continue;
01181 Vec_PtrWriteEntry( vVecTemp, m, NULL );
01182 break;
01183 }
01184 assert( m < Vec_PtrSize(vVecTemp) );
01185 pNode->fMarkB = 0;
01186 }
01187
01188
01189
01190
01203 bool Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode )
01204 {
01205 Abc_Obj_t * pFanout;
01206 int i, iFanin;
01207 Abc_ObjForEachFanout( pNode, pFanout, i )
01208 {
01209 iFanin = Vec_IntFind( &pFanout->vFanins, pNode->Id );
01210 assert( iFanin >= 0 );
01211 if ( Abc_ObjFaninC( pFanout, iFanin ) )
01212 return 1;
01213 }
01214 return 0;
01215 }
01216
01230 bool Abc_AigNodeHasComplFanoutEdgeTrav( Abc_Obj_t * pNode )
01231 {
01232 Abc_Obj_t * pFanout;
01233 int i, iFanin;
01234 Abc_ObjForEachFanout( pNode, pFanout, i )
01235 {
01236 if ( !Abc_NodeIsTravIdCurrent(pFanout) )
01237 continue;
01238 iFanin = Vec_IntFind( &pFanout->vFanins, pNode->Id );
01239 assert( iFanin >= 0 );
01240 if ( Abc_ObjFaninC( pFanout, iFanin ) )
01241 return 1;
01242 }
01243 return 0;
01244 }
01245
01246
01258 void Abc_AigPrintNode( Abc_Obj_t * pNode )
01259 {
01260 Abc_Obj_t * pNodeR = Abc_ObjRegular(pNode);
01261 if ( Abc_ObjIsCi(pNodeR) )
01262 {
01263 printf( "CI %4s%s.\n", Abc_ObjName(pNodeR), Abc_ObjIsComplement(pNode)? "\'" : "" );
01264 return;
01265 }
01266 if ( Abc_AigNodeIsConst(pNodeR) )
01267 {
01268 printf( "Constant 1 %s.\n", Abc_ObjIsComplement(pNode)? "(complemented)" : "" );
01269 return;
01270 }
01271
01272 printf( "%7s%s", Abc_ObjName(pNodeR), Abc_ObjIsComplement(pNode)? "\'" : "" );
01273 printf( " = " );
01274 printf( "%7s%s", Abc_ObjName(Abc_ObjFanin0(pNodeR)), Abc_ObjFaninC0(pNodeR)? "\'" : "" );
01275 printf( " * " );
01276 printf( "%7s%s", Abc_ObjName(Abc_ObjFanin1(pNodeR)), Abc_ObjFaninC1(pNodeR)? "\'" : "" );
01277 printf( "\n" );
01278 }
01279
01280
01292 bool Abc_AigNodeIsAcyclic( Abc_Obj_t * pNode, Abc_Obj_t * pRoot )
01293 {
01294 Abc_Obj_t * pFanin0, * pFanin1;
01295 Abc_Obj_t * pChild00, * pChild01;
01296 Abc_Obj_t * pChild10, * pChild11;
01297 if ( !Abc_AigNodeIsAnd(pNode) )
01298 return 1;
01299 pFanin0 = Abc_ObjFanin0(pNode);
01300 pFanin1 = Abc_ObjFanin1(pNode);
01301 if ( pRoot == pFanin0 || pRoot == pFanin1 )
01302 return 0;
01303 if ( Abc_ObjIsCi(pFanin0) )
01304 {
01305 pChild00 = NULL;
01306 pChild01 = NULL;
01307 }
01308 else
01309 {
01310 pChild00 = Abc_ObjFanin0(pFanin0);
01311 pChild01 = Abc_ObjFanin1(pFanin0);
01312 if ( pRoot == pChild00 || pRoot == pChild01 )
01313 return 0;
01314 }
01315 if ( Abc_ObjIsCi(pFanin1) )
01316 {
01317 pChild10 = NULL;
01318 pChild11 = NULL;
01319 }
01320 else
01321 {
01322 pChild10 = Abc_ObjFanin0(pFanin1);
01323 pChild11 = Abc_ObjFanin1(pFanin1);
01324 if ( pRoot == pChild10 || pRoot == pChild11 )
01325 return 0;
01326 }
01327 return 1;
01328 }
01329
01341 void Abc_AigCheckFaninOrder( Abc_Aig_t * pMan )
01342 {
01343 Abc_Obj_t * pEnt;
01344 int i;
01345 for ( i = 0; i < pMan->nBins; i++ )
01346 Abc_AigBinForEachEntry( pMan->pBins[i], pEnt )
01347 {
01348 if ( Abc_ObjRegular(Abc_ObjChild0(pEnt))->Id > Abc_ObjRegular(Abc_ObjChild1(pEnt))->Id )
01349 {
01350
01351
01352 printf( "Node %d has incorrect ordering of fanins.\n", pEnt->Id );
01353 }
01354 }
01355 }
01356
01368 void Abc_AigSetNodePhases( Abc_Ntk_t * pNtk )
01369 {
01370 Abc_Obj_t * pObj;
01371 int i;
01372 assert( Abc_NtkIsDfsOrdered(pNtk) );
01373 Abc_AigConst1(pNtk)->fPhase = 1;
01374 Abc_NtkForEachPi( pNtk, pObj, i )
01375 pObj->fPhase = 0;
01376 Abc_NtkForEachLatchOutput( pNtk, pObj, i )
01377 pObj->fPhase = Abc_LatchIsInit1(pObj);
01378 Abc_AigForEachAnd( pNtk, pObj, i )
01379 pObj->fPhase = (Abc_ObjFanin0(pObj)->fPhase ^ Abc_ObjFaninC0(pObj)) & (Abc_ObjFanin1(pObj)->fPhase ^ Abc_ObjFaninC1(pObj));
01380 Abc_NtkForEachPo( pNtk, pObj, i )
01381 pObj->fPhase = (Abc_ObjFanin0(pObj)->fPhase ^ Abc_ObjFaninC0(pObj));
01382 Abc_NtkForEachLatchInput( pNtk, pObj, i )
01383 pObj->fPhase = (Abc_ObjFanin0(pObj)->fPhase ^ Abc_ObjFaninC0(pObj));
01384 }
01385
01386
01387
01399 Vec_Ptr_t * Abc_AigUpdateStart( Abc_Aig_t * pMan, Vec_Ptr_t ** pvUpdatedNets )
01400 {
01401 assert( pMan->vAddedCells == NULL );
01402 pMan->vAddedCells = Vec_PtrAlloc( 1000 );
01403 pMan->vUpdatedNets = Vec_PtrAlloc( 1000 );
01404 *pvUpdatedNets = pMan->vUpdatedNets;
01405 return pMan->vAddedCells;
01406 }
01407
01419 void Abc_AigUpdateStop( Abc_Aig_t * pMan )
01420 {
01421 assert( pMan->vAddedCells != NULL );
01422 Vec_PtrFree( pMan->vAddedCells );
01423 Vec_PtrFree( pMan->vUpdatedNets );
01424 pMan->vAddedCells = NULL;
01425 pMan->vUpdatedNets = NULL;
01426 }
01427
01439 void Abc_AigUpdateReset( Abc_Aig_t * pMan )
01440 {
01441 assert( pMan->vAddedCells != NULL );
01442 Vec_PtrClear( pMan->vAddedCells );
01443 Vec_PtrClear( pMan->vUpdatedNets );
01444 }
01445
01457 int Abc_AigCountNext( Abc_Aig_t * pMan )
01458 {
01459 Abc_Obj_t * pAnd;
01460 int i, Counter = 0, CounterTotal = 0;
01461
01462 for ( i = 0; i < pMan->nBins; i++ )
01463 Abc_AigBinForEachEntry( pMan->pBins[i], pAnd )
01464 {
01465 Counter += (pAnd->pNext != NULL);
01466 CounterTotal++;
01467 }
01468 printf( "Counter = %d. Nodes = %d. Ave = %6.2f\n", Counter, CounterTotal, 1.0 * CounterTotal/pMan->nBins );
01469 return Counter;
01470 }
01471
01475
01476