00001
00021 #include "ivy.h"
00022
00026
00030
00042 Ivy_Obj_t * Ivy_ObjCreatePi( Ivy_Man_t * p )
00043 {
00044 return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, NULL, NULL, IVY_PI, IVY_INIT_NONE) );
00045 }
00046
00058 Ivy_Obj_t * Ivy_ObjCreatePo( Ivy_Man_t * p, Ivy_Obj_t * pDriver )
00059 {
00060 return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pDriver, NULL, IVY_PO, IVY_INIT_NONE) );
00061 }
00062
00074 Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost )
00075 {
00076 Ivy_Obj_t * pObj;
00077 assert( !Ivy_IsComplement(pGhost) );
00078 assert( Ivy_ObjIsGhost(pGhost) );
00079 assert( Ivy_TableLookup(p, pGhost) == NULL );
00080
00081 pObj = Ivy_ManFetchMemory( p );
00082 assert( Ivy_ObjIsNone(pObj) );
00083 pObj->Id = Vec_PtrSize(p->vObjs);
00084 Vec_PtrPush( p->vObjs, pObj );
00085
00086 pObj->Type = pGhost->Type;
00087 pObj->Init = pGhost->Init;
00088
00089 Ivy_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 );
00090
00091 if ( Ivy_ObjIsNode(pObj) )
00092 pObj->Level = Ivy_ObjLevelNew(pObj);
00093 else if ( Ivy_ObjIsLatch(pObj) )
00094 pObj->Level = 0;
00095 else if ( Ivy_ObjIsOneFanin(pObj) )
00096 pObj->Level = Ivy_ObjFanin0(pObj)->Level;
00097 else if ( !Ivy_ObjIsPi(pObj) )
00098 assert( 0 );
00099
00100 if ( Ivy_ObjIsNode(pObj) )
00101 pObj->fPhase = Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)) & Ivy_ObjFaninPhase(Ivy_ObjChild1(pObj));
00102 else if ( Ivy_ObjIsOneFanin(pObj) )
00103 pObj->fPhase = Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj));
00104
00105 if ( Ivy_ObjIsNode(pObj) )
00106 pObj->fFailTfo = Ivy_ObjFanin0(pObj)->fFailTfo | Ivy_ObjFanin1(pObj)->fFailTfo;
00107
00108 if ( Ivy_ObjIsExor(pObj) )
00109 {
00110 Ivy_ObjFanin0(pObj)->fExFan = 1;
00111 Ivy_ObjFanin1(pObj)->fExFan = 1;
00112 }
00113
00114 if ( Ivy_ObjIsPi(pObj) )
00115 Vec_PtrPush( p->vPis, pObj );
00116 else if ( Ivy_ObjIsPo(pObj) )
00117 Vec_PtrPush( p->vPos, pObj );
00118
00119
00120 if ( p->vRequired && Vec_IntSize(p->vRequired) <= pObj->Id )
00121 Vec_IntFillExtra( p->vRequired, 2 * Vec_IntSize(p->vRequired), 1000000 );
00122
00123 p->nObjs[Ivy_ObjType(pObj)]++;
00124 p->nCreated++;
00125
00126
00127
00128
00129
00130
00131 if ( p->pHaig )
00132 Ivy_ManHaigCreateObj( p, pObj );
00133 return pObj;
00134 }
00135
00147 void Ivy_ObjConnect( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFan0, Ivy_Obj_t * pFan1 )
00148 {
00149 assert( !Ivy_IsComplement(pObj) );
00150 assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || pFan1 != NULL );
00151
00152 pObj->pFanin0 = pFan0;
00153 pObj->pFanin1 = pFan1;
00154
00155 if ( Ivy_ObjFanin0(pObj) != NULL )
00156 {
00157 Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) );
00158 if ( p->fFanout )
00159 Ivy_ObjAddFanout( p, Ivy_ObjFanin0(pObj), pObj );
00160 }
00161 if ( Ivy_ObjFanin1(pObj) != NULL )
00162 {
00163 Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) );
00164 if ( p->fFanout )
00165 Ivy_ObjAddFanout( p, Ivy_ObjFanin1(pObj), pObj );
00166 }
00167
00168 Ivy_TableInsert( p, pObj );
00169 }
00170
00182 void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj )
00183 {
00184 assert( !Ivy_IsComplement(pObj) );
00185 assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || Ivy_ObjFanin1(pObj) != NULL );
00186
00187 if ( pObj->pFanin0 != NULL )
00188 {
00189 Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj));
00190 if ( p->fFanout )
00191 Ivy_ObjDeleteFanout( p, Ivy_ObjFanin0(pObj), pObj );
00192 }
00193 if ( pObj->pFanin1 != NULL )
00194 {
00195 Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj));
00196 if ( p->fFanout )
00197 Ivy_ObjDeleteFanout( p, Ivy_ObjFanin1(pObj), pObj );
00198 }
00199 assert( pObj->pNextFan0 == NULL );
00200 assert( pObj->pNextFan1 == NULL );
00201 assert( pObj->pPrevFan0 == NULL );
00202 assert( pObj->pPrevFan1 == NULL );
00203
00204 Ivy_TableDelete( p, pObj );
00205
00206 pObj->pFanin0 = NULL;
00207 pObj->pFanin1 = NULL;
00208 }
00209
00221 void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew )
00222 {
00223 Ivy_Obj_t * pFaninOld;
00224 assert( !Ivy_IsComplement(pObj) );
00225 pFaninOld = Ivy_ObjFanin0(pObj);
00226
00227 Ivy_ObjRefsDec( pFaninOld );
00228 if ( p->fFanout )
00229 Ivy_ObjDeleteFanout( p, pFaninOld, pObj );
00230
00231 pObj->pFanin0 = pFaninNew;
00232
00233 Ivy_ObjRefsInc( Ivy_Regular(pFaninNew) );
00234 if ( p->fFanout )
00235 Ivy_ObjAddFanout( p, Ivy_Regular(pFaninNew), pObj );
00236
00237 if ( !Ivy_ObjIsPi(pFaninOld) && !Ivy_ObjIsConst1(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 )
00238 Ivy_ObjDelete_rec( p, pFaninOld, 1 );
00239 }
00240
00252 void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
00253 {
00254 assert( !Ivy_IsComplement(pObj) );
00255 assert( Ivy_ObjRefs(pObj) == 0 || !fFreeTop );
00256
00257 p->nObjs[pObj->Type]--;
00258 p->nDeleted++;
00259
00260 Ivy_ObjDisconnect( p, pObj );
00261
00262 if ( Ivy_ObjIsPi(pObj) )
00263 Vec_PtrRemove( p->vPis, pObj );
00264 else if ( Ivy_ObjIsPo(pObj) )
00265 Vec_PtrRemove( p->vPos, pObj );
00266 else if ( p->fFanout && Ivy_ObjIsBuf(pObj) )
00267 Vec_PtrRemove( p->vBufs, pObj );
00268
00269 if ( fFreeTop )
00270 {
00271
00272 Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
00273 Ivy_ManRecycleMemory( p, pObj );
00274 }
00275 else
00276 {
00277 int nRefsOld = pObj->nRefs;
00278 Ivy_Obj_t * pFanout = pObj->pFanout;
00279 Ivy_ObjClean( pObj );
00280 pObj->pFanout = pFanout;
00281 pObj->nRefs = nRefsOld;
00282 }
00283 }
00284
00296 void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop )
00297 {
00298 Ivy_Obj_t * pFanin0, * pFanin1;
00299 assert( !Ivy_IsComplement(pObj) );
00300 assert( !Ivy_ObjIsNone(pObj) );
00301 if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsPi(pObj) )
00302 return;
00303 pFanin0 = Ivy_ObjFanin0(pObj);
00304 pFanin1 = Ivy_ObjFanin1(pObj);
00305 Ivy_ObjDelete( p, pObj, fFreeTop );
00306 if ( pFanin0 && !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 )
00307 Ivy_ObjDelete_rec( p, pFanin0, 1 );
00308 if ( pFanin1 && !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 )
00309 Ivy_ObjDelete_rec( p, pFanin1, 1 );
00310 }
00311
00325 void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel )
00326 {
00327 int nRefsOld;
00328
00329 assert( !Ivy_IsComplement(pObjOld) );
00330
00331 assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsPi(pObjOld) );
00332
00333 assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) );
00334
00335 assert( pObjOld != Ivy_Regular(pObjNew) );
00336
00337
00338
00339 if ( p->pHaig )
00340 {
00341
00342
00343
00344
00345
00346 Ivy_ManHaigCreateChoice( p, pObjOld, pObjNew );
00347 }
00348
00349 if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
00350 pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) );
00351 assert( !Ivy_IsComplement(pObjNew) );
00352 if ( fUpdateLevel )
00353 {
00354
00355
00356 if ( p->fFanout && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level )
00357 {
00358 assert( Ivy_ObjIsNode(pObjOld) );
00359 pObjOld->Level = pObjNew->Level;
00360 Ivy_ObjUpdateLevel_rec( p, pObjOld );
00361 }
00362
00363
00364
00365 if ( p->vRequired )
00366 {
00367 int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id);
00368 if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) )
00369 {
00370 Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew );
00371 Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew );
00372 }
00373 }
00374
00375 }
00376
00377 if ( fDeleteOld )
00378 Ivy_ObjDelete_rec( p, pObjOld, fFreeTop );
00379
00380 assert( Ivy_ObjFanin0(pObjNew) == NULL || pObjOld != Ivy_ObjFanin0(pObjNew) );
00381 assert( Ivy_ObjFanin1(pObjNew) == NULL || pObjOld != Ivy_ObjFanin1(pObjNew) );
00382
00383 if ( p->fFanout )
00384 {
00385 assert( pObjOld->pFanout != NULL );
00386 assert( pObjNew->pFanout == NULL );
00387 pObjNew->pFanout = pObjOld->pFanout;
00388 }
00389
00390 assert( Ivy_ObjRefs(pObjNew) == 0 );
00391 nRefsOld = pObjOld->nRefs;
00392 Ivy_ObjOverwrite( pObjOld, pObjNew );
00393 pObjOld->nRefs = nRefsOld;
00394
00395 if ( p->fFanout )
00396 {
00397 Ivy_ObjPatchFanout( p, Ivy_ObjFanin0(pObjOld), pObjNew, pObjOld );
00398 if ( Ivy_ObjFanin1(pObjOld) )
00399 Ivy_ObjPatchFanout( p, Ivy_ObjFanin1(pObjOld), pObjNew, pObjOld );
00400 }
00401
00402 Ivy_TableUpdate( p, pObjNew, pObjOld->Id );
00403
00404 Vec_PtrWriteEntry( p->vObjs, pObjNew->Id, NULL );
00405 Ivy_ManRecycleMemory( p, pObjNew );
00406
00407 if ( p->fFanout && Ivy_ObjIsBuf(pObjOld) )
00408 Vec_PtrPush( p->vBufs, pObjOld );
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 }
00425
00439 void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel )
00440 {
00441 Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult;
00442 if ( Ivy_ObjIsPo(pNode) )
00443 {
00444 if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) )
00445 return;
00446 pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) );
00447 Ivy_ObjPatchFanin0( p, pNode, pFanReal0 );
00448
00449 return;
00450 }
00451 if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) && !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) )
00452 return;
00453
00454 pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) );
00455 pFanReal1 = Ivy_ObjReal( Ivy_ObjChild1(pNode) );
00456
00457 if ( Ivy_ObjIsNode(pNode) )
00458 pResult = Ivy_Oper( p, pFanReal0, pFanReal1, Ivy_ObjType(pNode) );
00459 else if ( Ivy_ObjIsLatch(pNode) )
00460 pResult = Ivy_Latch( p, pFanReal0, Ivy_ObjInit(pNode) );
00461 else
00462 assert( 0 );
00463
00464
00465
00466
00467
00468
00469 Ivy_ObjReplace( p, pNode, pResult, 1, 0, fUpdateLevel );
00470 }
00471
00475
00476