00001
00021 #include "aig.h"
00022
00026
00030
00042 Aig_Obj_t * Aig_ObjCreatePi( Aig_Man_t * p )
00043 {
00044 Aig_Obj_t * pObj;
00045 pObj = Aig_ManFetchMemory( p );
00046 pObj->Type = AIG_OBJ_PI;
00047 Vec_PtrPush( p->vPis, pObj );
00048 p->nObjs[AIG_OBJ_PI]++;
00049 return pObj;
00050 }
00051
00063 Aig_Obj_t * Aig_ObjCreatePo( Aig_Man_t * p, Aig_Obj_t * pDriver )
00064 {
00065 Aig_Obj_t * pObj;
00066 pObj = Aig_ManFetchMemory( p );
00067 pObj->Type = AIG_OBJ_PO;
00068 Vec_PtrPush( p->vPos, pObj );
00069 Aig_ObjConnect( p, pObj, pDriver, NULL );
00070 p->nObjs[AIG_OBJ_PO]++;
00071 return pObj;
00072 }
00073
00074
00086 Aig_Obj_t * Aig_ObjCreate( Aig_Man_t * p, Aig_Obj_t * pGhost )
00087 {
00088 Aig_Obj_t * pObj;
00089 assert( !Aig_IsComplement(pGhost) );
00090 assert( Aig_ObjIsHash(pGhost) );
00091 assert( pGhost == &p->Ghost );
00092
00093 pObj = Aig_ManFetchMemory( p );
00094 pObj->Type = pGhost->Type;
00095
00096 Aig_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 );
00097
00098 p->nObjs[Aig_ObjType(pObj)]++;
00099 assert( pObj->pData == NULL );
00100 return pObj;
00101 }
00102
00114 void Aig_ObjConnect( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFan0, Aig_Obj_t * pFan1 )
00115 {
00116 assert( !Aig_IsComplement(pObj) );
00117 assert( !Aig_ObjIsPi(pObj) );
00118
00119 pObj->pFanin0 = pFan0;
00120 pObj->pFanin1 = pFan1;
00121
00122 if ( pFan0 != NULL )
00123 {
00124 assert( Aig_ObjFanin0(pObj)->Type > 0 );
00125 Aig_ObjRef( Aig_ObjFanin0(pObj) );
00126 if ( p->pFanData )
00127 Aig_ObjAddFanout( p, Aig_ObjFanin0(pObj), pObj );
00128 }
00129 if ( pFan1 != NULL )
00130 {
00131 assert( Aig_ObjFanin1(pObj)->Type > 0 );
00132 Aig_ObjRef( Aig_ObjFanin1(pObj) );
00133 if ( p->pFanData )
00134 Aig_ObjAddFanout( p, Aig_ObjFanin1(pObj), pObj );
00135 }
00136
00137 pObj->Level = Aig_ObjLevelNew( pObj );
00138 pObj->fPhase = Aig_ObjPhaseReal(pFan0) & Aig_ObjPhaseReal(pFan1);
00139
00140 if ( Aig_ObjIsHash(pObj) )
00141 Aig_TableInsert( p, pObj );
00142
00143
00144
00145 }
00146
00158 void Aig_ObjDisconnect( Aig_Man_t * p, Aig_Obj_t * pObj )
00159 {
00160 assert( !Aig_IsComplement(pObj) );
00161
00162 if ( pObj->pFanin0 != NULL )
00163 {
00164 if ( p->pFanData )
00165 Aig_ObjRemoveFanout( p, Aig_ObjFanin0(pObj), pObj );
00166 Aig_ObjDeref(Aig_ObjFanin0(pObj));
00167 }
00168 if ( pObj->pFanin1 != NULL )
00169 {
00170 if ( p->pFanData )
00171 Aig_ObjRemoveFanout( p, Aig_ObjFanin1(pObj), pObj );
00172 Aig_ObjDeref(Aig_ObjFanin1(pObj));
00173 }
00174
00175 if ( Aig_ObjIsHash(pObj) )
00176 Aig_TableDelete( p, pObj );
00177
00178 pObj->pFanin0 = NULL;
00179 pObj->pFanin1 = NULL;
00180
00181
00182
00183 }
00184
00196 void Aig_ObjDelete( Aig_Man_t * p, Aig_Obj_t * pObj )
00197 {
00198 assert( !Aig_IsComplement(pObj) );
00199 assert( !Aig_ObjIsTerm(pObj) );
00200 assert( Aig_ObjRefs(pObj) == 0 );
00201 if ( p->pFanData && Aig_ObjIsBuf(pObj) )
00202 Vec_PtrRemove( p->vBufs, pObj );
00203 p->nObjs[pObj->Type]--;
00204 Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
00205 Aig_ManRecycleMemory( p, pObj );
00206 }
00207
00219 void Aig_ObjDelete_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int fFreeTop )
00220 {
00221 Aig_Obj_t * pFanin0, * pFanin1;
00222 assert( !Aig_IsComplement(pObj) );
00223 if ( Aig_ObjIsConst1(pObj) || Aig_ObjIsPi(pObj) )
00224 return;
00225 assert( !Aig_ObjIsPo(pObj) );
00226 pFanin0 = Aig_ObjFanin0(pObj);
00227 pFanin1 = Aig_ObjFanin1(pObj);
00228 Aig_ObjDisconnect( p, pObj );
00229 if ( fFreeTop )
00230 Aig_ObjDelete( p, pObj );
00231 if ( pFanin0 && !Aig_ObjIsNone(pFanin0) && Aig_ObjRefs(pFanin0) == 0 )
00232 Aig_ObjDelete_rec( p, pFanin0, 1 );
00233 if ( pFanin1 && !Aig_ObjIsNone(pFanin1) && Aig_ObjRefs(pFanin1) == 0 )
00234 Aig_ObjDelete_rec( p, pFanin1, 1 );
00235 }
00236
00248 void Aig_ObjPatchFanin0( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pFaninNew )
00249 {
00250 Aig_Obj_t * pFaninOld;
00251 assert( !Aig_IsComplement(pObj) );
00252 assert( Aig_ObjIsPo(pObj) );
00253 pFaninOld = Aig_ObjFanin0(pObj);
00254
00255 if ( p->pFanData )
00256 Aig_ObjRemoveFanout( p, pFaninOld, pObj );
00257 Aig_ObjDeref( pFaninOld );
00258
00259 pObj->pFanin0 = pFaninNew;
00260
00261 if ( p->pFanData )
00262 Aig_ObjAddFanout( p, Aig_ObjFanin0(pObj), pObj );
00263 Aig_ObjRef( Aig_ObjFanin0(pObj) );
00264
00265 if ( !Aig_ObjIsPi(pFaninOld) && !Aig_ObjIsConst1(pFaninOld) && Aig_ObjRefs(pFaninOld) == 0 )
00266 Aig_ObjDelete_rec( p, pFaninOld, 1 );
00267 }
00268
00280 void Aig_NodeFixBufferFanins( Aig_Man_t * p, Aig_Obj_t * pObj, int fNodesOnly, int fUpdateLevel )
00281 {
00282 Aig_Obj_t * pFanReal0, * pFanReal1, * pResult;
00283 p->nBufFixes++;
00284 if ( Aig_ObjIsPo(pObj) )
00285 {
00286 assert( Aig_ObjIsBuf(Aig_ObjFanin0(pObj)) );
00287 pFanReal0 = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
00288 assert( Aig_ObjPhaseReal(Aig_ObjChild0(pObj)) == Aig_ObjPhaseReal(pFanReal0) );
00289 Aig_ObjPatchFanin0( p, pObj, pFanReal0 );
00290 return;
00291 }
00292 assert( Aig_ObjIsNode(pObj) );
00293 assert( Aig_ObjIsBuf(Aig_ObjFanin0(pObj)) || Aig_ObjIsBuf(Aig_ObjFanin1(pObj)) );
00294
00295 pFanReal0 = Aig_ObjReal_rec( Aig_ObjChild0(pObj) );
00296 pFanReal1 = Aig_ObjReal_rec( Aig_ObjChild1(pObj) );
00297
00298 if ( Aig_ObjIsNode(pObj) )
00299 pResult = Aig_Oper( p, pFanReal0, pFanReal1, Aig_ObjType(pObj) );
00300
00301
00302 else
00303 assert( 0 );
00304
00305 Aig_ObjReplace( p, pObj, pResult, fNodesOnly, fUpdateLevel );
00306 }
00307
00319 int Aig_ManPropagateBuffers( Aig_Man_t * p, int fNodesOnly, int fUpdateLevel )
00320 {
00321 Aig_Obj_t * pObj;
00322 int nSteps;
00323 assert( p->pFanData );
00324 for ( nSteps = 0; Vec_PtrSize(p->vBufs) > 0; nSteps++ )
00325 {
00326
00327 for ( pObj = Vec_PtrEntryLast(p->vBufs); Aig_ObjIsBuf(pObj); pObj = Aig_ObjFanout0(p, pObj) );
00328
00329 Aig_NodeFixBufferFanins( p, pObj, fNodesOnly, fUpdateLevel );
00330
00331 if ( nSteps > 1000000 )
00332 {
00333 printf( "Error: A cycle is encountered while propagating buffers.\n" );
00334 break;
00335 }
00336 }
00337 return nSteps;
00338 }
00339
00354 void Aig_ObjReplace( Aig_Man_t * p, Aig_Obj_t * pObjOld, Aig_Obj_t * pObjNew, int fNodesOnly, int fUpdateLevel )
00355 {
00356 Aig_Obj_t * pObjNewR = Aig_Regular(pObjNew);
00357
00358 assert( !Aig_IsComplement(pObjOld) );
00359
00360 assert( !Aig_ObjIsPi(pObjOld) && !Aig_ObjIsPo(pObjOld) );
00361
00362 assert( !Aig_ObjIsBuf(pObjNewR) && !Aig_ObjIsPo(pObjNewR) );
00363
00364 assert( pObjOld != pObjNewR );
00365
00366 assert( pObjOld != Aig_ObjFanin0(pObjNewR) );
00367 assert( pObjOld != Aig_ObjFanin1(pObjNewR) );
00368
00369 pObjNewR->nRefs++;
00370 Aig_ObjDelete_rec( p, pObjOld, 0 );
00371 pObjNewR->nRefs--;
00372
00373 p->nObjs[pObjOld->Type]--;
00374 if ( Aig_IsComplement(pObjNew) || Aig_ObjRefs(pObjNew) > 0 || (fNodesOnly && !Aig_ObjIsNode(pObjNew)) )
00375 {
00376 pObjOld->Type = AIG_OBJ_BUF;
00377 Aig_ObjConnect( p, pObjOld, pObjNew, NULL );
00378 p->nBufReplaces++;
00379 }
00380 else
00381 {
00382 Aig_Obj_t * pFanin0 = pObjNew->pFanin0;
00383 Aig_Obj_t * pFanin1 = pObjNew->pFanin1;
00384 int LevelOld = pObjOld->Level;
00385 pObjOld->Type = pObjNew->Type;
00386 Aig_ObjDisconnect( p, pObjNew );
00387 Aig_ObjConnect( p, pObjOld, pFanin0, pFanin1 );
00388
00389 Aig_ObjDelete( p, pObjNew );
00390
00391 if ( p->pFanData )
00392 {
00393 pObjOld->Level = LevelOld;
00394 Aig_ManUpdateLevel( p, pObjOld );
00395 }
00396 if ( fUpdateLevel )
00397 {
00398 Aig_ObjClearReverseLevel( p, pObjOld );
00399 Aig_ManUpdateReverseLevel( p, pObjOld );
00400 }
00401 }
00402 p->nObjs[pObjOld->Type]++;
00403
00404 if ( p->pFanData && Aig_ObjIsBuf(pObjOld) )
00405 {
00406 Vec_PtrPush( p->vBufs, pObjOld );
00407 p->nBufMax = AIG_MAX( p->nBufMax, Vec_PtrSize(p->vBufs) );
00408 Aig_ManPropagateBuffers( p, fNodesOnly, fUpdateLevel );
00409 }
00410 }
00411
00415
00416