00001
00021 #include "abc.h"
00022
00026
00030
00042 int Abc_NtkHaigStart( Abc_Ntk_t * pNtk )
00043 {
00044 Hop_Man_t * p;
00045 Abc_Obj_t * pObj, * pTemp;
00046 int i;
00047 assert( Abc_NtkIsStrash(pNtk) );
00048
00049 if ( pNtk->pHaig )
00050 {
00051 Abc_NtkHaigStop( pNtk );
00052 assert( pNtk->pHaig == NULL );
00053 printf( "Warning: Previous history AIG was removed.\n" );
00054 }
00055
00056 Abc_NtkForEachObj( pNtk, pObj, i )
00057 assert( pObj->pEquiv == NULL );
00058
00059 p = Hop_ManStart();
00060 p->vObjs = Vec_PtrAlloc( 4096 );
00061 Vec_PtrPush( p->vObjs, Hop_ManConst1(p) );
00062
00063 Abc_AigConst1(pNtk)->pEquiv = Hop_ManConst1(p);
00064
00065 Abc_NtkForEachCi( pNtk, pObj, i )
00066 pObj->pEquiv = Hop_ObjCreatePi(p);
00067
00068 Abc_NtkForEachNode( pNtk, pObj, i )
00069 pObj->pEquiv = Hop_And( p, Abc_ObjChild0Equiv(pObj), Abc_ObjChild1Equiv(pObj) );
00070
00071 if ( Abc_NtkGetChoiceNum( pNtk ) )
00072 {
00073
00074 printf( "Warning: The choice nodes in the original AIG are converted into HAIG.\n" );
00075 Abc_NtkForEachNode( pNtk, pObj, i )
00076 {
00077 if ( !Abc_AigNodeIsChoice( pObj ) )
00078 continue;
00079 for ( pTemp = pObj->pData; pTemp; pTemp = pTemp->pData )
00080 Hop_ObjCreateChoice( pObj->pEquiv, pTemp->pEquiv );
00081 }
00082 }
00083
00084 if ( !Hop_ManCheck(p) )
00085 {
00086 printf( "Abc_NtkHaigStart: Check for History AIG has failed.\n" );
00087 Hop_ManStop(p);
00088 return 0;
00089 }
00090 pNtk->pHaig = p;
00091 return 1;
00092 }
00093
00105 int Abc_NtkHaigStop( Abc_Ntk_t * pNtk )
00106 {
00107 Abc_Obj_t * pObj;
00108 int i;
00109 assert( Abc_NtkIsStrash(pNtk) );
00110 if ( pNtk->pHaig == NULL )
00111 {
00112 printf( "Warning: History AIG is not allocated.\n" );
00113 return 1;
00114 }
00115 Abc_NtkForEachObj( pNtk, pObj, i )
00116 pObj->pEquiv = NULL;
00117 Hop_ManStop( pNtk->pHaig );
00118 pNtk->pHaig = NULL;
00119 return 1;
00120 }
00121
00133 void Abc_NtkHaigTranfer( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
00134 {
00135 Abc_Obj_t * pObj;
00136 int i;
00137 if ( pNtkOld->pHaig == NULL )
00138 return;
00139
00140 assert( pNtkNew->pHaig == NULL );
00141 pNtkNew->pHaig = pNtkOld->pHaig;
00142 pNtkOld->pHaig = NULL;
00143
00144 Abc_AigConst1(pNtkOld)->pCopy->pEquiv = Abc_AigConst1(pNtkOld)->pEquiv;
00145
00146 Abc_NtkForEachCi( pNtkOld, pObj, i )
00147 pObj->pCopy->pEquiv = pObj->pEquiv;
00148 }
00149
00150
00151
00163 Vec_Ptr_t * Abc_NtkHaigCollectMembers( Hop_Man_t * p )
00164 {
00165 Vec_Ptr_t * vObjs;
00166 Hop_Obj_t * pObj;
00167 int i;
00168 vObjs = Vec_PtrAlloc( 4098 );
00169 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00170 {
00171 if ( pObj->pData == NULL )
00172 continue;
00173 pObj->pData = Hop_ObjRepr( pObj );
00174 Vec_PtrPush( vObjs, pObj );
00175 }
00176 return vObjs;
00177 }
00178
00190 Vec_Ptr_t * Abc_NtkHaigCreateClasses( Vec_Ptr_t * vMembers )
00191 {
00192 Vec_Ptr_t * vClasses;
00193 Hop_Obj_t * pObj, * pRepr;
00194 int i;
00195
00196
00197 vClasses = Vec_PtrAlloc( 4098 );
00198 Vec_PtrForEachEntry( vMembers, pObj, i )
00199 {
00200 pRepr = pObj->pData;
00201 assert( pRepr->pData == NULL );
00202 if ( pRepr->fMarkA == 0 )
00203 {
00204 pRepr->fMarkA = 1;
00205 Vec_PtrPush( vClasses, pRepr );
00206 }
00207 }
00208
00209
00210 Vec_PtrForEachEntry( vClasses, pObj, i )
00211 {
00212 pObj->fMarkA = 0;
00213 pObj->pData = pObj;
00214 }
00215
00216
00217 Vec_PtrForEachEntry( vMembers, pObj, i )
00218 {
00219 pRepr = pObj->pData;
00220 if ( ((Hop_Obj_t *)pRepr->pData)->Id > pObj->Id )
00221 pRepr->pData = pObj;
00222 }
00223
00224
00225 Vec_PtrForEachEntry( vMembers, pObj, i )
00226 {
00227 pRepr = pObj->pData;
00228 pObj->pData = pRepr->pData;
00229 assert( ((Hop_Obj_t *)pObj->pData)->Id <= pObj->Id );
00230 }
00231
00232
00233 Vec_PtrForEachEntry( vClasses, pObj, i )
00234 {
00235 pRepr = pObj->pData;
00236 assert( pRepr->pData == pRepr );
00237
00238 Vec_PtrWriteEntry( vClasses, i, pRepr );
00239 Vec_PtrPush( vMembers, pObj );
00240 }
00241
00242 Vec_PtrForEachEntry( vMembers, pObj, i )
00243 if ( pObj->pData == pObj )
00244 pObj->pData = NULL;
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 return vClasses;
00263 }
00264
00276 int Abc_NtkHaigCountFans( Hop_Man_t * p )
00277 {
00278 Hop_Obj_t * pObj;
00279 int i, Counter = 0;
00280 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00281 {
00282 if ( pObj->pData == NULL )
00283 continue;
00284 if ( Hop_ObjRefs(pObj) > 0 )
00285 Counter++;
00286 }
00287 printf( "The number of class members with fanouts = %5d.\n", Counter );
00288 return Counter;
00289 }
00290
00291
00303 static inline Hop_Obj_t * Hop_ObjReprHop( Hop_Obj_t * pObj )
00304 {
00305 Hop_Obj_t * pRepr;
00306 assert( pObj->pNext != NULL );
00307 if ( pObj->pData == NULL )
00308 return pObj->pNext;
00309 pRepr = pObj->pData;
00310 assert( pRepr->pData == pRepr );
00311 return Hop_NotCond( pRepr->pNext, pObj->fPhase ^ pRepr->fPhase );
00312 }
00313
00325 static inline Hop_Obj_t * Hop_ObjChild0Hop( Hop_Obj_t * pObj ) { return Hop_NotCond( Hop_ObjReprHop(Hop_ObjFanin0(pObj)), Hop_ObjFaninC0(pObj) ); }
00326 static inline Hop_Obj_t * Hop_ObjChild1Hop( Hop_Obj_t * pObj ) { return Hop_NotCond( Hop_ObjReprHop(Hop_ObjFanin1(pObj)), Hop_ObjFaninC1(pObj) ); }
00327
00339 Hop_Man_t * Abc_NtkHaigReconstruct( Hop_Man_t * p )
00340 {
00341 Hop_Man_t * pNew;
00342 Hop_Obj_t * pObj;
00343 int i, Counter = 0;
00344 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00345 pObj->pNext = NULL;
00346
00347 pNew = Hop_ManStart();
00348 pNew->vObjs = Vec_PtrAlloc( p->nCreated );
00349 Vec_PtrPush( pNew->vObjs, Hop_ManConst1(pNew) );
00350
00351 Hop_ManConst1(p)->pNext = Hop_ManConst1(pNew);
00352
00353 Hop_ManForEachPi( p, pObj, i )
00354 pObj->pNext = Hop_ObjCreatePi(pNew);
00355
00356 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00357 {
00358 if ( !Hop_ObjIsNode(pObj) )
00359 continue;
00360 pObj->pNext = Hop_And( pNew, Hop_ObjChild0Hop(pObj), Hop_ObjChild1Hop(pObj) );
00361
00362 if ( Hop_ManConst1(pNew) == Hop_Regular(pObj->pNext) )
00363 Counter++;
00364 if ( pObj->pData )
00365 Hop_Regular(pObj->pNext)->pData = Hop_Regular(((Hop_Obj_t *)pObj->pData)->pNext);
00366 }
00367
00368
00369 Hop_ManForEachPo( p, pObj, i )
00370 Hop_ObjCreatePo( pNew, Hop_ObjChild0Hop(pObj) );
00371
00372 if ( !Hop_ManCheck(pNew) )
00373 {
00374 printf( "Abc_NtkHaigReconstruct: Check for History AIG has failed.\n" );
00375 Hop_ManStop(pNew);
00376 return NULL;
00377 }
00378 return pNew;
00379 }
00380
00381
00393 int Abc_NtkHaigCheckTfi_rec( Abc_Obj_t * pNode, Abc_Obj_t * pOld )
00394 {
00395 if ( pNode == NULL )
00396 return 0;
00397 if ( pNode == pOld )
00398 return 1;
00399
00400 if ( Abc_ObjIsCi(pNode) )
00401 return 0;
00402 assert( Abc_ObjIsNode(pNode) );
00403
00404 if ( Abc_NodeIsTravIdCurrent( pNode ) )
00405 return 0;
00406
00407 Abc_NodeSetTravIdCurrent( pNode );
00408
00409 if ( Abc_NtkHaigCheckTfi_rec( Abc_ObjFanin0(pNode), pOld ) )
00410 return 1;
00411 if ( Abc_NtkHaigCheckTfi_rec( Abc_ObjFanin1(pNode), pOld ) )
00412 return 1;
00413
00414 return Abc_NtkHaigCheckTfi_rec( pNode->pData, pOld );
00415 }
00416
00428 int Abc_NtkHaigCheckTfi( Abc_Ntk_t * pNtk, Abc_Obj_t * pOld, Abc_Obj_t * pNew )
00429 {
00430 assert( !Abc_ObjIsComplement(pOld) );
00431 assert( !Abc_ObjIsComplement(pNew) );
00432 Abc_NtkIncrementTravId(pNtk);
00433 return Abc_NtkHaigCheckTfi_rec( pNew, pOld );
00434 }
00435
00447 static inline Abc_Obj_t * Hop_ObjChild0Next( Hop_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Hop_ObjFanin0(pObj)->pNext, Hop_ObjFaninC0(pObj) ); }
00448 static inline Abc_Obj_t * Hop_ObjChild1Next( Hop_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Hop_ObjFanin1(pObj)->pNext, Hop_ObjFaninC1(pObj) ); }
00449
00461 Abc_Ntk_t * Abc_NtkHaigRecreateAig( Abc_Ntk_t * pNtk, Hop_Man_t * p )
00462 {
00463 Abc_Ntk_t * pNtkAig;
00464 Abc_Obj_t * pObjOld, * pObjAbcThis, * pObjAbcRepr;
00465 Hop_Obj_t * pObj;
00466 int i;
00467 assert( p->nCreated == Vec_PtrSize(p->vObjs) );
00468
00469
00470 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
00471
00472
00473 Hop_ManConst1(p)->pNext = (Hop_Obj_t *)Abc_AigConst1( pNtkAig );
00474 Hop_ManForEachPi( p, pObj, i )
00475 pObj->pNext = (Hop_Obj_t *)Abc_NtkCi( pNtkAig, i );
00476
00477
00478 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00479 {
00480 if ( !Hop_ObjIsNode(pObj) )
00481 continue;
00482 pObj->pNext = (Hop_Obj_t *)Abc_AigAnd( pNtkAig->pManFunc, Hop_ObjChild0Next(pObj), Hop_ObjChild1Next(pObj) );
00483 assert( !Hop_IsComplement(pObj->pNext) );
00484 }
00485
00486
00487 Abc_NtkForEachCo( pNtk, pObjOld, i )
00488 Abc_ObjAddFanin( pObjOld->pCopy, Hop_ObjChild0Next(Hop_ManPo(p,i)) );
00489
00490
00491 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00492 {
00493
00494 if ( pObj->pData == NULL )
00495 continue;
00496
00497 if ( pObj->pData == pObj )
00498 continue;
00499
00500 if ( !Hop_ObjIsNode(pObj->pData) )
00501 continue;
00502
00503 pObjAbcThis = (Abc_Obj_t *)pObj->pNext;
00504 pObjAbcRepr = (Abc_Obj_t *)((Hop_Obj_t *)pObj->pData)->pNext;
00505
00506 assert( pObjAbcThis->pData == NULL );
00507
00508 assert( Abc_ObjFanoutNum(pObjAbcThis) == 0 );
00509
00510 assert( pObjAbcRepr != pObjAbcThis );
00511
00512 if ( !Abc_NtkHaigCheckTfi( pNtkAig, pObjAbcRepr, pObjAbcThis ) )
00513 {
00514
00515 while ( pObjAbcRepr->pData )
00516 pObjAbcRepr = pObjAbcRepr->pData;
00517
00518 pObjAbcRepr->pData = pObjAbcThis;
00519 }
00520 }
00521
00522
00523
00524
00525
00526 if ( !Abc_NtkCheck( pNtkAig ) )
00527 {
00528 printf( "Abc_NtkHaigUse: The network check has failed.\n" );
00529 Abc_NtkDelete( pNtkAig );
00530 return NULL;
00531 }
00532 return pNtkAig;
00533 }
00534
00546 void Abc_NtkHaigResetReprsOld( Hop_Man_t * pMan )
00547 {
00548 Vec_Ptr_t * vMembers, * vClasses;
00549
00550
00551 vMembers = Abc_NtkHaigCollectMembers( pMan );
00552 printf( "Collected %6d class members.\n", Vec_PtrSize(vMembers) );
00553
00554
00555 vClasses = Abc_NtkHaigCreateClasses( vMembers );
00556 printf( "Collected %6d classes. (Ave = %5.2f)\n", Vec_PtrSize(vClasses),
00557 (float)(Vec_PtrSize(vMembers))/Vec_PtrSize(vClasses) );
00558
00559 Vec_PtrFree( vMembers );
00560 Vec_PtrFree( vClasses );
00561 }
00562
00574 int Abc_NtkHaigResetReprs( Hop_Man_t * p )
00575 {
00576 Hop_Obj_t * pObj, * pRepr;
00577 int i, nClasses, nMembers, nFanouts, nNormals;
00578
00579 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00580 {
00581
00582 pRepr = pObj->pData;
00583 if ( pRepr && pRepr->pData == pObj )
00584 pRepr->pData = pRepr;
00585
00586 if ( pObj->pData == pObj )
00587 pObj->pData = NULL;
00588 }
00589
00590 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00591 {
00592 if ( pObj->pData == NULL )
00593 continue;
00594
00595 pRepr = Hop_ObjRepr( pObj );
00596 pRepr->pData = pRepr;
00597
00598 pObj->pData = pRepr;
00599 }
00600
00601 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00602 {
00603 if ( pObj->pData == NULL )
00604 continue;
00605 pRepr = Hop_ObjRepr( pObj );
00606 if ( pRepr->Id > pObj->Id )
00607 {
00608 pRepr->pData = pObj;
00609 pObj->pData = pObj;
00610 }
00611 else
00612 pObj->pData = pRepr;
00613 }
00614
00615 nMembers = nClasses = nFanouts = nNormals = 0;
00616 Vec_PtrForEachEntry( p->vObjs, pObj, i )
00617 {
00618 if ( pObj->pData == NULL )
00619 continue;
00620
00621 nMembers++;
00622
00623 if ( pObj->pData == pObj )
00624 nClasses++;
00625 else if ( Hop_ObjRefs(pObj) > 0 )
00626 nFanouts++;
00627 else
00628 nNormals++;
00629
00630 pRepr = Hop_ObjRepr( pObj );
00631 assert( pObj->pData == pRepr );
00632 assert( pRepr->Id <= pObj->Id );
00633 }
00634
00635
00636 return nFanouts;
00637 }
00638
00650 Abc_Ntk_t * Abc_NtkHaigUse( Abc_Ntk_t * pNtk )
00651 {
00652 Hop_Man_t * pMan, * pManTemp;
00653 Abc_Ntk_t * pNtkAig;
00654 Abc_Obj_t * pObj;
00655 int i;
00656
00657
00658 assert( Abc_NtkIsStrash(pNtk) );
00659 if ( pNtk->pHaig == NULL )
00660 {
00661 printf( "Warning: History AIG is not available.\n" );
00662 return NULL;
00663 }
00664
00665
00666
00667
00668
00669 Abc_NtkForEachCo( pNtk, pObj, i )
00670 Hop_ObjCreatePo( pNtk->pHaig, Abc_ObjChild0Equiv(pObj) );
00671
00672
00673 Abc_NtkForEachObj( pNtk, pObj, i )
00674 pObj->pEquiv = NULL;
00675 pMan = pNtk->pHaig;
00676 pNtk->pHaig = 0;
00677
00678
00679 while ( Abc_NtkHaigResetReprs( pMan ) )
00680 {
00681 pMan = Abc_NtkHaigReconstruct( pManTemp = pMan );
00682 Hop_ManStop( pManTemp );
00683 }
00684
00685
00686 pNtkAig = Abc_NtkHaigRecreateAig( pNtk, pMan );
00687 Hop_ManStop( pMan );
00688
00689
00690 return pNtkAig;
00691 }
00692
00704 Abc_Ntk_t * Abc_NtkHopRemoveLoops( Abc_Ntk_t * pNtk, Hop_Man_t * pMan )
00705 {
00706 Abc_Ntk_t * pNtkAig;
00707 Hop_Man_t * pManTemp;
00708
00709
00710 while ( Abc_NtkHaigResetReprs( pMan ) )
00711 {
00712 pMan = Abc_NtkHaigReconstruct( pManTemp = pMan );
00713 Hop_ManStop( pManTemp );
00714 }
00715
00716
00717 pNtkAig = Abc_NtkHaigRecreateAig( pNtk, pMan );
00718 Hop_ManStop( pMan );
00719 return pNtkAig;
00720 }
00721
00725
00726