00001
00021 #include "darInt.h"
00022
00026
00027 static Aig_Obj_t * Dar_Balance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
00028 static Vec_Ptr_t * Dar_BalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
00029 static int Dar_BalanceFindLeft( Vec_Ptr_t * vSuper );
00030 static void Dar_BalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor );
00031 static void Dar_BalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj );
00032 static Aig_Obj_t * Dar_BalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel );
00033
00037
00049 Aig_Man_t * Dar_ManBalance( Aig_Man_t * p, int fUpdateLevel )
00050 {
00051 Aig_Man_t * pNew;
00052 Aig_Obj_t * pObj, * pDriver, * pObjNew;
00053 Vec_Vec_t * vStore;
00054 int i;
00055
00056 pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
00057 pNew->pName = Aig_UtilStrsav( p->pName );
00058 pNew->nRegs = p->nRegs;
00059 pNew->nAsserts = p->nAsserts;
00060 if ( p->vFlopNums )
00061 pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
00062
00063 Aig_ManCleanData( p );
00064 Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
00065 Aig_ManForEachPi( p, pObj, i )
00066 pObj->pData = Aig_ObjCreatePi(pNew);
00067
00068 vStore = Vec_VecAlloc( 50 );
00069 Aig_ManForEachPo( p, pObj, i )
00070 {
00071 pDriver = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
00072 pObjNew = Dar_Balance_rec( pNew, Aig_Regular(pDriver), vStore, 0, fUpdateLevel );
00073 pObjNew = Aig_NotCond( pObjNew, Aig_IsComplement(pDriver) );
00074 Aig_ObjCreatePo( pNew, pObjNew );
00075 }
00076 Vec_VecFree( vStore );
00077
00078 if ( (i = Aig_ManCleanup( pNew )) )
00079 printf( "Cleanup after balancing removed %d dangling nodes.\n", i );
00080
00081 if ( !Aig_ManCheck(pNew) )
00082 printf( "Dar_ManBalance(): The check has failed.\n" );
00083 return pNew;
00084 }
00085
00097 Aig_Obj_t * Dar_Balance_rec( Aig_Man_t * pNew, Aig_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
00098 {
00099 Aig_Obj_t * pObjNew;
00100 Vec_Ptr_t * vSuper;
00101 int i;
00102 assert( !Aig_IsComplement(pObjOld) );
00103 assert( !Aig_ObjIsBuf(pObjOld) );
00104
00105 if ( pObjOld->pData )
00106 return pObjOld->pData;
00107 assert( Aig_ObjIsNode(pObjOld) );
00108
00109 vSuper = Dar_BalanceCone( pObjOld, vStore, Level );
00110
00111 if ( vSuper->nSize == 0 )
00112 return pObjOld->pData = Aig_ManConst0(pNew);
00113 if ( Vec_PtrSize(vSuper) < 2 )
00114 printf( "BUG!\n" );
00115
00116 for ( i = 0; i < Vec_PtrSize(vSuper); i++ )
00117 {
00118 pObjNew = Dar_Balance_rec( pNew, Aig_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
00119 vSuper->pArray[i] = Aig_NotCond( pObjNew, Aig_IsComplement(vSuper->pArray[i]) );
00120 }
00121
00122 pObjNew = Dar_BalanceBuildSuper( pNew, vSuper, Aig_ObjType(pObjOld), fUpdateLevel );
00123
00124
00125 assert( pObjOld->pData == NULL );
00126 return pObjOld->pData = pObjNew;
00127 }
00128
00140 int Dar_BalanceCone_rec( Aig_Obj_t * pRoot, Aig_Obj_t * pObj, Vec_Ptr_t * vSuper )
00141 {
00142 int RetValue1, RetValue2, i;
00143
00144 if ( Aig_Regular(pObj)->fMarkB )
00145 {
00146
00147 for ( i = 0; i < vSuper->nSize; i++ )
00148 if ( vSuper->pArray[i] == pObj )
00149 return 1;
00150
00151 for ( i = 0; i < vSuper->nSize; i++ )
00152 if ( vSuper->pArray[i] == Aig_Not(pObj) )
00153 return -1;
00154 assert( 0 );
00155 return 0;
00156 }
00157
00158 if ( pObj != pRoot && (Aig_IsComplement(pObj) || Aig_ObjType(pObj) != Aig_ObjType(pRoot) || Aig_ObjRefs(pObj) > 1) )
00159 {
00160 Vec_PtrPush( vSuper, pObj );
00161 Aig_Regular(pObj)->fMarkB = 1;
00162 return 0;
00163 }
00164 assert( !Aig_IsComplement(pObj) );
00165 assert( Aig_ObjIsNode(pObj) );
00166
00167 RetValue1 = Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild0(pObj) ), vSuper );
00168 RetValue2 = Dar_BalanceCone_rec( pRoot, Aig_ObjReal_rec( Aig_ObjChild1(pObj) ), vSuper );
00169 if ( RetValue1 == -1 || RetValue2 == -1 )
00170 return -1;
00171
00172 return RetValue1 || RetValue2;
00173 }
00174
00186 Vec_Ptr_t * Dar_BalanceCone( Aig_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
00187 {
00188 Vec_Ptr_t * vNodes;
00189 int RetValue, i;
00190 assert( !Aig_IsComplement(pObj) );
00191
00192 if ( Vec_VecSize( vStore ) <= Level )
00193 Vec_VecPush( vStore, Level, 0 );
00194
00195 vNodes = Vec_VecEntry( vStore, Level );
00196 Vec_PtrClear( vNodes );
00197
00198 RetValue = Dar_BalanceCone_rec( pObj, pObj, vNodes );
00199 assert( vNodes->nSize > 1 );
00200
00201 Vec_PtrForEachEntry( vNodes, pObj, i )
00202 Aig_Regular(pObj)->fMarkB = 0;
00203
00204
00205 if ( RetValue == -1 )
00206 vNodes->nSize = 0;
00207 return vNodes;
00208 }
00209
00221 int Aig_NodeCompareLevelsDecrease( Aig_Obj_t ** pp1, Aig_Obj_t ** pp2 )
00222 {
00223 int Diff = Aig_ObjLevel(Aig_Regular(*pp1)) - Aig_ObjLevel(Aig_Regular(*pp2));
00224 if ( Diff > 0 )
00225 return -1;
00226 if ( Diff < 0 )
00227 return 1;
00228 return 0;
00229 }
00230
00242 Aig_Obj_t * Dar_BalanceBuildSuper( Aig_Man_t * p, Vec_Ptr_t * vSuper, Aig_Type_t Type, int fUpdateLevel )
00243 {
00244 Aig_Obj_t * pObj1, * pObj2;
00245 int LeftBound;
00246 assert( vSuper->nSize > 1 );
00247
00248 Vec_PtrSort( vSuper, Aig_NodeCompareLevelsDecrease );
00249
00250 while ( vSuper->nSize > 1 )
00251 {
00252
00253 LeftBound = (!fUpdateLevel)? 0 : Dar_BalanceFindLeft( vSuper );
00254
00255 Dar_BalancePermute( p, vSuper, LeftBound, Type == AIG_OBJ_EXOR );
00256
00257 pObj1 = Vec_PtrPop(vSuper);
00258 pObj2 = Vec_PtrPop(vSuper);
00259 Dar_BalancePushUniqueOrderByLevel( vSuper, Aig_Oper(p, pObj1, pObj2, Type) );
00260 }
00261 return Vec_PtrEntry(vSuper, 0);
00262 }
00263
00279 int Dar_BalanceFindLeft( Vec_Ptr_t * vSuper )
00280 {
00281 Aig_Obj_t * pObjRight, * pObjLeft;
00282 int Current;
00283
00284 if ( Vec_PtrSize(vSuper) < 3 )
00285 return 0;
00286
00287 Current = Vec_PtrSize(vSuper) - 2;
00288 pObjRight = Vec_PtrEntry( vSuper, Current );
00289
00290 for ( Current--; Current >= 0; Current-- )
00291 {
00292
00293 pObjLeft = Vec_PtrEntry( vSuper, Current );
00294
00295 if ( Aig_ObjLevel(Aig_Regular(pObjLeft)) != Aig_ObjLevel(Aig_Regular(pObjRight)) )
00296 break;
00297 }
00298 Current++;
00299
00300 pObjLeft = Vec_PtrEntry( vSuper, Current );
00301 assert( Aig_ObjLevel(Aig_Regular(pObjLeft)) == Aig_ObjLevel(Aig_Regular(pObjRight)) );
00302 return Current;
00303 }
00304
00317 void Dar_BalancePermute( Aig_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
00318 {
00319 Aig_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
00320 int RightBound, i;
00321
00322 RightBound = Vec_PtrSize(vSuper) - 2;
00323 assert( LeftBound <= RightBound );
00324 if ( LeftBound == RightBound )
00325 return;
00326
00327 pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 );
00328 pObj2 = Vec_PtrEntry( vSuper, RightBound );
00329 if ( Aig_Regular(pObj1) == p->pConst1 || Aig_Regular(pObj2) == p->pConst1 )
00330 return;
00331
00332 for ( i = RightBound; i >= LeftBound; i-- )
00333 {
00334 pObj3 = Vec_PtrEntry( vSuper, i );
00335 if ( Aig_Regular(pObj3) == p->pConst1 )
00336 {
00337 Vec_PtrWriteEntry( vSuper, i, pObj2 );
00338 Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
00339 return;
00340 }
00341 pGhost = Aig_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_OBJ_EXOR : AIG_OBJ_AND );
00342 if ( Aig_TableLookup( p, pGhost ) )
00343 {
00344 if ( pObj3 == pObj2 )
00345 return;
00346 Vec_PtrWriteEntry( vSuper, i, pObj2 );
00347 Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
00348 return;
00349 }
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 }
00363
00375 void Dar_BalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Aig_Obj_t * pObj )
00376 {
00377 Aig_Obj_t * pObj1, * pObj2;
00378 int i;
00379 if ( Vec_PtrPushUnique(vStore, pObj) )
00380 return;
00381
00382 for ( i = vStore->nSize-1; i > 0; i-- )
00383 {
00384 pObj1 = vStore->pArray[i ];
00385 pObj2 = vStore->pArray[i-1];
00386 if ( Aig_ObjLevel(Aig_Regular(pObj1)) <= Aig_ObjLevel(Aig_Regular(pObj2)) )
00387 break;
00388 vStore->pArray[i ] = pObj2;
00389 vStore->pArray[i-1] = pObj1;
00390 }
00391 }
00392
00393
00397
00398