00001
00021 #include "abc.h"
00022
00026
00027 #define ABC_DC_MAX_NODES (1<<15)
00028
00029 typedef unsigned short Odc_Lit_t;
00030
00031 typedef struct Odc_Obj_t_ Odc_Obj_t;
00032 struct Odc_Obj_t_
00033 {
00034 Odc_Lit_t iFan0;
00035 Odc_Lit_t iFan1;
00036 Odc_Lit_t iNext;
00037 unsigned short TravId;
00038 unsigned uData;
00039 unsigned uMask;
00040 };
00041
00042 typedef struct Odc_Man_t_ Odc_Man_t;
00043 struct Odc_Man_t_
00044 {
00045
00046 int nVarsMax;
00047 int nLevels;
00048 int fVerbose;
00049 int fVeryVerbose;
00050 int nPercCutoff;
00051
00052
00053 Abc_Obj_t * pNode;
00054 Vec_Ptr_t * vLeaves;
00055 Vec_Ptr_t * vRoots;
00056 Vec_Ptr_t * vBranches;
00057
00058
00059
00060 int nPis;
00061 int nObjs;
00062 int nObjsAlloc;
00063 Odc_Obj_t * pObjs;
00064 Odc_Lit_t iRoot;
00065 unsigned short nTravIds;
00066
00067 Odc_Lit_t * pTable;
00068 int nTableSize;
00069 Vec_Int_t * vUsedSpots;
00070
00071
00072 int nBits;
00073 int nWords;
00074 Vec_Ptr_t * vTruths;
00075 Vec_Ptr_t * vTruthsElem;
00076 unsigned * puTruth;
00077
00078
00079 int nWins;
00080 int nWinsEmpty;
00081 int nSimsEmpty;
00082 int nQuantsOver;
00083 int nWinsFinish;
00084 int nTotalDcs;
00085
00086
00087 int timeClean;
00088 int timeWin;
00089 int timeMiter;
00090 int timeSim;
00091 int timeQuant;
00092 int timeTruth;
00093 int timeTotal;
00094 int timeAbort;
00095 };
00096
00097
00098
00099 static inline int Odc_PiNum( Odc_Man_t * p ) { return p->nPis; }
00100 static inline int Odc_NodeNum( Odc_Man_t * p ) { return p->nObjs - p->nPis - 1; }
00101 static inline int Odc_ObjNum( Odc_Man_t * p ) { return p->nObjs; }
00102
00103
00104 static inline int Odc_IsComplement( Odc_Lit_t Lit ) { return Lit & (Odc_Lit_t)1; }
00105 static inline Odc_Lit_t Odc_Regular( Odc_Lit_t Lit ) { return Lit & ~(Odc_Lit_t)1; }
00106 static inline Odc_Lit_t Odc_Not( Odc_Lit_t Lit ) { return Lit ^ (Odc_Lit_t)1; }
00107 static inline Odc_Lit_t Odc_NotCond( Odc_Lit_t Lit, int c ) { return Lit ^ (Odc_Lit_t)(c!=0); }
00108
00109
00110 static inline Odc_Lit_t Odc_Const0() { return 1; }
00111 static inline Odc_Lit_t Odc_Const1() { return 0; }
00112 static inline Odc_Lit_t Odc_Var( Odc_Man_t * p, int i ) { assert( i >= 0 && i < p->nPis ); return (i+1) << 1; }
00113 static inline int Odc_IsConst( Odc_Lit_t Lit ) { return Lit < (Odc_Lit_t)2; }
00114 static inline int Odc_IsTerm( Odc_Man_t * p, Odc_Lit_t Lit ) { return (int)(Lit>>1) <= p->nPis; }
00115
00116
00117 static inline Odc_Obj_t * Odc_ObjNew( Odc_Man_t * p ) { assert( p->nObjs < p->nObjsAlloc ); return p->pObjs + p->nObjs++; }
00118 static inline Odc_Lit_t Odc_Obj2Lit( Odc_Man_t * p, Odc_Obj_t * pObj ) { assert( pObj ); return (pObj - p->pObjs) << 1; }
00119 static inline Odc_Obj_t * Odc_Lit2Obj( Odc_Man_t * p, Odc_Lit_t Lit ) { assert( !(Lit & 1) && (int)(Lit>>1) < p->nObjs ); return p->pObjs + (Lit>>1); }
00120
00121
00122 static inline Odc_Lit_t Odc_ObjChild0( Odc_Obj_t * pObj ) { return pObj->iFan0; }
00123 static inline Odc_Lit_t Odc_ObjChild1( Odc_Obj_t * pObj ) { return pObj->iFan1; }
00124 static inline Odc_Lit_t Odc_ObjFanin0( Odc_Obj_t * pObj ) { return Odc_Regular(pObj->iFan0); }
00125 static inline Odc_Lit_t Odc_ObjFanin1( Odc_Obj_t * pObj ) { return Odc_Regular(pObj->iFan1); }
00126 static inline int Odc_ObjFaninC0( Odc_Obj_t * pObj ) { return Odc_IsComplement(pObj->iFan0); }
00127 static inline int Odc_ObjFaninC1( Odc_Obj_t * pObj ) { return Odc_IsComplement(pObj->iFan1); }
00128
00129
00130 static inline void Odc_ManIncrementTravId( Odc_Man_t * p ) { p->nTravIds++; }
00131 static inline void Odc_ObjSetTravIdCurrent( Odc_Man_t * p, Odc_Obj_t * pObj ) { pObj->TravId = p->nTravIds; }
00132 static inline int Odc_ObjIsTravIdCurrent( Odc_Man_t * p, Odc_Obj_t * pObj ) { return (int )((int)pObj->TravId == p->nTravIds); }
00133
00134
00135 static inline unsigned * Odc_ObjTruth( Odc_Man_t * p, Odc_Lit_t Lit ) { assert( !(Lit & 1) ); return Vec_PtrEntry(p->vTruths, Lit >> 1); }
00136
00137
00138 #define Odc_ForEachPi( p, Lit, i ) \
00139 for ( i = 0; (i < Odc_PiNum(p)) && (((Lit) = Odc_Var(p, i)), 1); i++ )
00140 #define Odc_ForEachAnd( p, pObj, i ) \
00141 for ( i = 1 + Odc_CiNum(p); (i < Odc_ObjNum(p)) && ((pObj) = (p)->pObjs + i); i++ )
00142
00143
00144
00145 extern Odc_Man_t * Abc_NtkDontCareAlloc( int nVarsMax, int nLevels, int fVerbose, int fVeryVerbose );
00146 extern void Abc_NtkDontCareClear( Odc_Man_t * p );
00147 extern void Abc_NtkDontCareFree( Odc_Man_t * p );
00148 extern int Abc_NtkDontCareCompute( Odc_Man_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, unsigned * puTruth );
00149
00153
00166 Odc_Man_t * Abc_NtkDontCareAlloc( int nVarsMax, int nLevels, int fVerbose, int fVeryVerbose )
00167 {
00168 Odc_Man_t * p;
00169 unsigned * pData;
00170 int i, k;
00171 p = ALLOC( Odc_Man_t, 1 );
00172 memset( p, 0, sizeof(Odc_Man_t) );
00173 assert( nVarsMax > 4 && nVarsMax < 16 );
00174 assert( nLevels > 0 && nLevels < 10 );
00175
00176 srand( 0xABC );
00177
00178
00179 p->nVarsMax = nVarsMax;
00180 p->nLevels = nLevels;
00181 p->fVerbose = fVerbose;
00182 p->fVeryVerbose = fVeryVerbose;
00183 p->nPercCutoff = 10;
00184
00185
00186 p->vRoots = Vec_PtrAlloc( 128 );
00187 p->vBranches = Vec_PtrAlloc( 128 );
00188
00189
00190
00191 p->nObjsAlloc = ABC_DC_MAX_NODES;
00192 p->pObjs = ALLOC( Odc_Obj_t, p->nObjsAlloc * sizeof(Odc_Obj_t) );
00193 p->nPis = nVarsMax + 32;
00194 p->nObjs = 1 + p->nPis;
00195 memset( p->pObjs, 0, p->nObjs * sizeof(Odc_Obj_t) );
00196
00197 for ( i = 0; i < 32; i++ )
00198 p->pObjs[1 + p->nVarsMax + i].uMask = (1 << i);
00199
00200 p->nTableSize = p->nObjsAlloc/3 + 1;
00201 p->pTable = ALLOC( Odc_Lit_t, p->nTableSize * sizeof(Odc_Lit_t) );
00202 memset( p->pTable, 0, p->nTableSize * sizeof(Odc_Lit_t) );
00203 p->vUsedSpots = Vec_IntAlloc( 1000 );
00204
00205
00206 p->nWords = Abc_TruthWordNum( p->nVarsMax );
00207 p->nBits = p->nWords * 8 * sizeof(unsigned);
00208 p->vTruths = Vec_PtrAllocSimInfo( p->nObjsAlloc, p->nWords );
00209 p->vTruthsElem = Vec_PtrAllocSimInfo( p->nVarsMax, p->nWords );
00210
00211
00212 Abc_InfoFill( Vec_PtrEntry(p->vTruths, 0), p->nWords );
00213 for ( k = 0; k < p->nVarsMax; k++ )
00214 {
00215
00216 pData = Vec_PtrEntry( p->vTruthsElem, k );
00217 Abc_InfoClear( pData, p->nWords );
00218 for ( i = 0; i < p->nBits; i++ )
00219 if ( i & (1 << k) )
00220 pData[i>>5] |= (1 << (i&31));
00221 }
00222
00223
00224 for ( k = p->nVarsMax; k < p->nPis; k++ )
00225 {
00226 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
00227 Abc_InfoRandom( pData, p->nWords );
00228 }
00229
00230
00231 p->iRoot = 0xffff;
00232 return p;
00233 }
00234
00246 void Abc_NtkDontCareClear( Odc_Man_t * p )
00247 {
00248 int clk = clock();
00249
00250 if ( Vec_IntSize(p->vUsedSpots) > p->nTableSize/3 )
00251 memset( p->pTable, 0, sizeof(Odc_Lit_t) * p->nTableSize );
00252 else
00253 {
00254 int iSpot, i;
00255 Vec_IntForEachEntry( p->vUsedSpots, iSpot, i )
00256 p->pTable[iSpot] = 0;
00257 }
00258 Vec_IntClear( p->vUsedSpots );
00259
00260 p->nObjs = 1 + p->nPis;
00261
00262 p->iRoot = 0xffff;
00263
00264 p->timeClean += clock() - clk;
00265 }
00266
00278 void Abc_NtkDontCareFree( Odc_Man_t * p )
00279 {
00280 if ( p->fVerbose )
00281 {
00282 printf( "Wins = %5d. Empty = %5d. SimsEmpty = %5d. QuantOver = %5d. WinsFinish = %5d.\n",
00283 p->nWins, p->nWinsEmpty, p->nSimsEmpty, p->nQuantsOver, p->nWinsFinish );
00284 printf( "Ave DCs per window = %6.2f %%. Ave DCs per finished window = %6.2f %%.\n",
00285 1.0*p->nTotalDcs/p->nWins, 1.0*p->nTotalDcs/p->nWinsFinish );
00286 printf( "Runtime stats of the ODC manager:\n" );
00287 PRT( "Cleaning ", p->timeClean );
00288 PRT( "Windowing ", p->timeWin );
00289 PRT( "Miter ", p->timeMiter );
00290 PRT( "Simulation ", p->timeSim );
00291 PRT( "Quantifying ", p->timeQuant );
00292 PRT( "Truth table ", p->timeTruth );
00293 PRT( "TOTAL ", p->timeTotal );
00294 PRT( "Aborted ", p->timeAbort );
00295 }
00296 Vec_PtrFree( p->vRoots );
00297 Vec_PtrFree( p->vBranches );
00298 Vec_PtrFree( p->vTruths );
00299 Vec_PtrFree( p->vTruthsElem );
00300 Vec_IntFree( p->vUsedSpots );
00301 free( p->pObjs );
00302 free( p->pTable );
00303 free( p );
00304 }
00305
00306
00307
00319 void Abc_NtkDontCareWinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit, Abc_Obj_t * pNode )
00320 {
00321 Abc_Obj_t * pFanout;
00322 int i;
00323 if ( Abc_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit || pObj == pNode )
00324 return;
00325 if ( Abc_NodeIsTravIdCurrent(pObj) )
00326 return;
00327 Abc_NodeSetTravIdCurrent( pObj );
00329
00330 if ( Abc_ObjFanoutNum(pObj) > 100 )
00331 return;
00333 Abc_ObjForEachFanout( pObj, pFanout, i )
00334 Abc_NtkDontCareWinSweepLeafTfo_rec( pFanout, nLevelLimit, pNode );
00335 }
00336
00348 void Abc_NtkDontCareWinSweepLeafTfo( Odc_Man_t * p )
00349 {
00350 Abc_Obj_t * pObj;
00351 int i;
00352 Abc_NtkIncrementTravId( p->pNode->pNtk );
00353 Vec_PtrForEachEntry( p->vLeaves, pObj, i )
00354 Abc_NtkDontCareWinSweepLeafTfo_rec( pObj, p->pNode->Level + p->nLevels, p->pNode );
00355 }
00356
00368 void Abc_NtkDontCareWinCollectRoots_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vRoots )
00369 {
00370 Abc_Obj_t * pFanout;
00371 int i;
00372 assert( Abc_ObjIsNode(pObj) );
00373 assert( Abc_NodeIsTravIdCurrent(pObj) );
00374
00375 Abc_ObjForEachFanout( pObj, pFanout, i )
00376 if ( !Abc_NodeIsTravIdCurrent(pFanout) )
00377 break;
00378
00379 if ( i < Abc_ObjFanoutNum(pObj) )
00380 {
00381 Vec_PtrPushUnique( vRoots, pObj );
00382 return;
00383 }
00384
00385 Abc_ObjForEachFanout( pObj, pFanout, i )
00386 Abc_NtkDontCareWinCollectRoots_rec( pFanout, vRoots );
00387 }
00388
00401 void Abc_NtkDontCareWinCollectRoots( Odc_Man_t * p )
00402 {
00403 assert( !Abc_NodeIsTravIdCurrent(p->pNode) );
00404
00405 Abc_NodeSetTravIdCurrent( p->pNode );
00406
00407 Vec_PtrClear( p->vRoots );
00408 Abc_NtkDontCareWinCollectRoots_rec( p->pNode, p->vRoots );
00409 }
00410
00422 int Abc_NtkDontCareWinAddMissing_rec( Odc_Man_t * p, Abc_Obj_t * pObj )
00423 {
00424 Abc_Obj_t * pFanin;
00425 int i;
00426
00427 if ( Abc_NodeIsTravIdCurrent(pObj) )
00428 return 1;
00429
00430 if ( !Abc_NodeIsTravIdPrevious(pObj) || Abc_ObjIsCi(pObj) )
00431 {
00432 Abc_NodeSetTravIdCurrent( pObj );
00433 Vec_PtrPush( p->vBranches, pObj );
00434 return Vec_PtrSize(p->vBranches) <= 32;
00435 }
00436
00437 Abc_ObjForEachFanin( pObj, pFanin, i )
00438 if ( !Abc_NtkDontCareWinAddMissing_rec( p, pFanin ) )
00439 return 0;
00440 return 1;
00441 }
00442
00454 int Abc_NtkDontCareWinAddMissing( Odc_Man_t * p )
00455 {
00456 Abc_Obj_t * pObj;
00457 int i;
00458
00459 Abc_NtkIncrementTravId( p->pNode->pNtk );
00460 Vec_PtrForEachEntry( p->vLeaves, pObj, i )
00461 Abc_NodeSetTravIdCurrent( pObj );
00462
00463 Vec_PtrClear( p->vBranches );
00464 Vec_PtrForEachEntry( p->vRoots, pObj, i )
00465 if ( !Abc_NtkDontCareWinAddMissing_rec( p, pObj ) )
00466 return 0;
00467 return 1;
00468 }
00469
00481 int Abc_NtkDontCareWindow( Odc_Man_t * p )
00482 {
00483
00484 Abc_NtkDontCareWinSweepLeafTfo( p );
00485
00486 Abc_NtkDontCareWinCollectRoots( p );
00487 if ( Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode )
00488 {
00489
00490 return 0;
00491 }
00492
00493 if ( !Abc_NtkDontCareWinAddMissing( p ) )
00494 {
00495
00496 return 0;
00497 }
00498 return 1;
00499 }
00500
00501
00502
00503
00504
00516 static inline unsigned Odc_HashKey( Odc_Lit_t iFan0, Odc_Lit_t iFan1, int TableSize )
00517 {
00518 unsigned Key = 0;
00519 Key ^= Odc_Regular(iFan0) * 7937;
00520 Key ^= Odc_Regular(iFan1) * 2971;
00521 Key ^= Odc_IsComplement(iFan0) * 911;
00522 Key ^= Odc_IsComplement(iFan1) * 353;
00523 return Key % TableSize;
00524 }
00525
00537 static inline Odc_Lit_t * Odc_HashLookup( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
00538 {
00539 Odc_Obj_t * pObj;
00540 Odc_Lit_t * pEntry;
00541 unsigned uHashKey;
00542 assert( iFan0 < iFan1 );
00543
00544 uHashKey = Odc_HashKey( iFan0, iFan1, p->nTableSize );
00545
00546 if ( p->pTable[uHashKey] == 0 )
00547 Vec_IntPush( p->vUsedSpots, uHashKey );
00548
00549 for ( pEntry = p->pTable + uHashKey; *pEntry; pEntry = &pObj->iNext )
00550 {
00551 pObj = Odc_Lit2Obj( p, *pEntry );
00552 if ( pObj->iFan0 == iFan0 && pObj->iFan1 == iFan1 )
00553 return pEntry;
00554 }
00555 return pEntry;
00556 }
00557
00569 static inline Odc_Lit_t Odc_And( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
00570 {
00571 Odc_Obj_t * pObj;
00572 Odc_Lit_t * pEntry;
00573 unsigned uMask0, uMask1;
00574 int Temp;
00575
00576 if ( iFan0 == iFan1 )
00577 return iFan0;
00578 if ( iFan0 == Odc_Not(iFan1) )
00579 return Odc_Const0();
00580 if ( Odc_Regular(iFan0) == Odc_Const1() )
00581 return iFan0 == Odc_Const1() ? iFan1 : Odc_Const0();
00582 if ( Odc_Regular(iFan1) == Odc_Const1() )
00583 return iFan1 == Odc_Const1() ? iFan0 : Odc_Const0();
00584
00585 if ( iFan0 > iFan1 )
00586 Temp = iFan0, iFan0 = iFan1, iFan1 = Temp;
00587
00588 pEntry = Odc_HashLookup( p, iFan0, iFan1 );
00589 if ( *pEntry )
00590 return *pEntry;
00591
00592 pObj = Odc_ObjNew( p );
00593 pObj->iFan0 = iFan0;
00594 pObj->iFan1 = iFan1;
00595 pObj->iNext = 0;
00596 pObj->TravId = 0;
00597
00598 uMask0 = Odc_Lit2Obj(p, Odc_Regular(iFan0))->uMask;
00599 uMask1 = Odc_Lit2Obj(p, Odc_Regular(iFan1))->uMask;
00600 pObj->uMask = uMask0 | uMask1;
00601
00602 *pEntry = Odc_Obj2Lit( p, pObj );
00603 return *pEntry;
00604 }
00605
00617 static inline Odc_Lit_t Odc_Or( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
00618 {
00619 return Odc_Not( Odc_And(p, Odc_Not(iFan0), Odc_Not(iFan1)) );
00620 }
00621
00633 static inline Odc_Lit_t Odc_Xor( Odc_Man_t * p, Odc_Lit_t iFan0, Odc_Lit_t iFan1 )
00634 {
00635 return Odc_Or( p, Odc_And(p, iFan0, Odc_Not(iFan1)), Odc_And(p, Odc_Not(iFan0), iFan1) );
00636 }
00637
00638
00639
00640
00641
00653 void * Abc_NtkDontCareTransfer_rec( Odc_Man_t * p, Abc_Obj_t * pNode, Abc_Obj_t * pPivot )
00654 {
00655 unsigned uData0, uData1;
00656 Odc_Lit_t uLit0, uLit1, uRes0, uRes1;
00657 assert( !Abc_ObjIsComplement(pNode) );
00658
00659 if ( Abc_NodeIsTravIdCurrent(pNode) )
00660 return pNode->pCopy;
00661 Abc_NodeSetTravIdCurrent(pNode);
00662 assert( Abc_ObjIsNode(pNode) );
00663
00664 if ( pNode == pPivot )
00665 return pNode->pCopy = (void *)((Odc_Const1() << 16) | Odc_Const0());
00666
00667 uData0 = (unsigned)Abc_NtkDontCareTransfer_rec( p, Abc_ObjFanin0(pNode), pPivot );
00668 uData1 = (unsigned)Abc_NtkDontCareTransfer_rec( p, Abc_ObjFanin1(pNode), pPivot );
00669
00670 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 & 0xffff), Abc_ObjFaninC0(pNode) );
00671 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 & 0xffff), Abc_ObjFaninC1(pNode) );
00672 uRes0 = Odc_And( p, uLit0, uLit1 );
00673
00674 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 >> 16), Abc_ObjFaninC0(pNode) );
00675 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 >> 16), Abc_ObjFaninC1(pNode) );
00676 uRes1 = Odc_And( p, uLit0, uLit1 );
00677
00678 return pNode->pCopy = (void *)((uRes1 << 16) | uRes0);
00679 }
00680
00692 int Abc_NtkDontCareTransfer( Odc_Man_t * p )
00693 {
00694 Abc_Obj_t * pObj;
00695 Odc_Lit_t uRes0, uRes1;
00696 Odc_Lit_t uLit;
00697 unsigned uData;
00698 int i;
00699 Abc_NtkIncrementTravId( p->pNode->pNtk );
00700
00701 Vec_PtrForEachEntry( p->vLeaves, pObj, i )
00702 {
00703 uLit = Odc_Var( p, i );
00704 pObj->pCopy = (void *)((uLit << 16) | uLit);
00705 Abc_NodeSetTravIdCurrent(pObj);
00706 }
00707
00708 Vec_PtrForEachEntry( p->vBranches, pObj, i )
00709 {
00710 uLit = Odc_Var( p, i+p->nVarsMax );
00711 pObj->pCopy = (void *)((uLit << 16) | uLit);
00712 Abc_NodeSetTravIdCurrent(pObj);
00713 }
00714
00715 p->iRoot = Odc_Const0();
00716 Vec_PtrForEachEntry( p->vRoots, pObj, i )
00717 {
00718 uData = (unsigned)Abc_NtkDontCareTransfer_rec( p, pObj, p->pNode );
00719
00720 uRes0 = uData & 0xffff;
00721 uRes1 = uData >> 16;
00722
00723
00724 uLit = Odc_Xor( p, uRes0, uRes1 );
00725 p->iRoot = Odc_Or( p, p->iRoot, uLit );
00726 }
00727 return 1;
00728 }
00729
00730
00742 unsigned Abc_NtkDontCareCofactors_rec( Odc_Man_t * p, Odc_Lit_t Lit, unsigned uMask )
00743 {
00744 Odc_Obj_t * pObj;
00745 unsigned uData0, uData1;
00746 Odc_Lit_t uLit0, uLit1, uRes0, uRes1;
00747 assert( !Odc_IsComplement(Lit) );
00748
00749 pObj = Odc_Lit2Obj( p, Lit );
00750 if ( Odc_ObjIsTravIdCurrent(p, pObj) )
00751 return pObj->uData;
00752 Odc_ObjSetTravIdCurrent(p, pObj);
00753
00754 if ( (pObj->uMask & uMask) == 0 )
00755 return pObj->uData = ((Lit << 16) | Lit);
00756
00757 if ( pObj->uMask == uMask && Odc_IsTerm(p, Lit) )
00758 return pObj->uData = ((Odc_Const1() << 16) | Odc_Const0());
00759
00760 uData0 = Abc_NtkDontCareCofactors_rec( p, Odc_ObjFanin0(pObj), uMask );
00761 uData1 = Abc_NtkDontCareCofactors_rec( p, Odc_ObjFanin1(pObj), uMask );
00762
00763 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 & 0xffff), Odc_ObjFaninC0(pObj) );
00764 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 & 0xffff), Odc_ObjFaninC1(pObj) );
00765 uRes0 = Odc_And( p, uLit0, uLit1 );
00766
00767 uLit0 = Odc_NotCond( (Odc_Lit_t)(uData0 >> 16), Odc_ObjFaninC0(pObj) );
00768 uLit1 = Odc_NotCond( (Odc_Lit_t)(uData1 >> 16), Odc_ObjFaninC1(pObj) );
00769 uRes1 = Odc_And( p, uLit0, uLit1 );
00770
00771 return pObj->uData = ((uRes1 << 16) | uRes0);
00772 }
00773
00785 int Abc_NtkDontCareQuantify( Odc_Man_t * p )
00786 {
00787 Odc_Lit_t uRes0, uRes1;
00788 unsigned uData;
00789 int i;
00790 assert( p->iRoot < 0xffff );
00791 assert( Vec_PtrSize(p->vBranches) <= 32 );
00792 for ( i = 0; i < Vec_PtrSize(p->vBranches); i++ )
00793 {
00794
00795 Odc_ManIncrementTravId( p );
00796 uData = Abc_NtkDontCareCofactors_rec( p, Odc_Regular(p->iRoot), (1 << i) );
00797 uRes0 = Odc_NotCond( (Odc_Lit_t)(uData & 0xffff), Odc_IsComplement(p->iRoot) );
00798 uRes1 = Odc_NotCond( (Odc_Lit_t)(uData >> 16), Odc_IsComplement(p->iRoot) );
00799
00800 p->iRoot = Odc_Or( p, uRes0, uRes1 );
00801
00802 if ( Odc_ObjNum(p) > ABC_DC_MAX_NODES/2 )
00803 return 0;
00804 }
00805 assert( p->nObjs <= p->nObjsAlloc );
00806 return 1;
00807 }
00808
00809
00810
00822 void Abc_NtkDontCareSimulateSetElem2( Odc_Man_t * p )
00823 {
00824 unsigned * pData;
00825 int i, k;
00826 for ( k = 0; k < p->nVarsMax; k++ )
00827 {
00828 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
00829 Abc_InfoClear( pData, p->nWords );
00830 for ( i = 0; i < p->nBits; i++ )
00831 if ( i & (1 << k) )
00832 pData[i>>5] |= (1 << (i&31));
00833 }
00834 }
00835
00847 void Abc_NtkDontCareSimulateSetElem( Odc_Man_t * p )
00848 {
00849 unsigned * pData, * pData2;
00850 int k;
00851 for ( k = 0; k < p->nVarsMax; k++ )
00852 {
00853 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
00854 pData2 = Vec_PtrEntry( p->vTruthsElem, k );
00855 Abc_InfoCopy( pData, pData2, p->nWords );
00856 }
00857 }
00858
00870 void Abc_NtkDontCareSimulateSetRand( Odc_Man_t * p )
00871 {
00872 unsigned * pData;
00873 int w, k, Number;
00874 for ( w = 0; w < p->nWords; w++ )
00875 {
00876 Number = rand();
00877 for ( k = 0; k < p->nVarsMax; k++ )
00878 {
00879 pData = Odc_ObjTruth( p, Odc_Var(p, k) );
00880 pData[w] = (Number & (1<<k)) ? ~0 : 0;
00881 }
00882 }
00883 }
00884
00896 int Abc_NtkDontCareCountMintsWord( Odc_Man_t * p, unsigned * puTruth )
00897 {
00898 int w, Counter = 0;
00899 for ( w = 0; w < p->nWords; w++ )
00900 if ( puTruth[w] )
00901 Counter++;
00902 return Counter;
00903 }
00904
00916 void Abc_NtkDontCareTruthOne( Odc_Man_t * p, Odc_Lit_t Lit )
00917 {
00918 Odc_Obj_t * pObj;
00919 unsigned * pInfo, * pInfo1, * pInfo2;
00920 int k, fComp1, fComp2;
00921 assert( !Odc_IsComplement( Lit ) );
00922 assert( !Odc_IsTerm( p, Lit ) );
00923
00924 pObj = Odc_Lit2Obj( p, Lit );
00925 pInfo = Odc_ObjTruth( p, Lit );
00926 pInfo1 = Odc_ObjTruth( p, Odc_ObjFanin0(pObj) );
00927 pInfo2 = Odc_ObjTruth( p, Odc_ObjFanin1(pObj) );
00928 fComp1 = Odc_ObjFaninC0( pObj );
00929 fComp2 = Odc_ObjFaninC1( pObj );
00930
00931 if ( fComp1 && fComp2 )
00932 for ( k = 0; k < p->nWords; k++ )
00933 pInfo[k] = ~pInfo1[k] & ~pInfo2[k];
00934 else if ( fComp1 && !fComp2 )
00935 for ( k = 0; k < p->nWords; k++ )
00936 pInfo[k] = ~pInfo1[k] & pInfo2[k];
00937 else if ( !fComp1 && fComp2 )
00938 for ( k = 0; k < p->nWords; k++ )
00939 pInfo[k] = pInfo1[k] & ~pInfo2[k];
00940 else
00941 for ( k = 0; k < p->nWords; k++ )
00942 pInfo[k] = pInfo1[k] & pInfo2[k];
00943 }
00944
00956 void Abc_NtkDontCareSimulate_rec( Odc_Man_t * p, Odc_Lit_t Lit )
00957 {
00958 Odc_Obj_t * pObj;
00959 assert( !Odc_IsComplement(Lit) );
00960
00961 if ( Odc_IsTerm(p, Lit) )
00962 return;
00963
00964 pObj = Odc_Lit2Obj( p, Lit );
00965 if ( Odc_ObjIsTravIdCurrent(p, pObj) )
00966 return;
00967 Odc_ObjSetTravIdCurrent(p, pObj);
00968
00969 Abc_NtkDontCareSimulate_rec( p, Odc_ObjFanin0(pObj) );
00970 Abc_NtkDontCareSimulate_rec( p, Odc_ObjFanin1(pObj) );
00971
00972 Abc_NtkDontCareTruthOne( p, Lit );
00973 }
00974
00986 int Abc_NtkDontCareSimulate( Odc_Man_t * p, unsigned * puTruth )
00987 {
00988 Odc_ManIncrementTravId( p );
00989 Abc_NtkDontCareSimulate_rec( p, Odc_Regular(p->iRoot) );
00990 Abc_InfoCopy( puTruth, Odc_ObjTruth(p, Odc_Regular(p->iRoot)), p->nWords );
00991 if ( Odc_IsComplement(p->iRoot) )
00992 Abc_InfoNot( puTruth, p->nWords );
00993 return Extra_TruthCountOnes( puTruth, p->nVarsMax );
00994 }
00995
01007 int Abc_NtkDontCareSimulateBefore( Odc_Man_t * p, unsigned * puTruth )
01008 {
01009 int nIters = 2;
01010 int nRounds, Counter, r;
01011
01012 nRounds = p->nBits / p->nWords;
01013 Counter = 0;
01014 for ( r = 0; r < nIters; r++ )
01015 {
01016 Abc_NtkDontCareSimulateSetRand( p );
01017 Abc_NtkDontCareSimulate( p, puTruth );
01018 Counter += Abc_NtkDontCareCountMintsWord( p, puTruth );
01019 }
01020
01021 Counter = Counter * nRounds / nIters;
01022 return Counter;
01023 }
01024
01037 int Abc_NtkDontCareCompute( Odc_Man_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, unsigned * puTruth )
01038 {
01039 int nMints, RetValue;
01040 int clk, clkTotal = clock();
01041
01042 p->nWins++;
01043
01044
01045 assert( !Abc_ObjIsComplement(pNode) );
01046 assert( Abc_ObjIsNode(pNode) );
01047 assert( Vec_PtrSize(vLeaves) <= p->nVarsMax );
01048 p->vLeaves = vLeaves;
01049 p->pNode = pNode;
01050
01051
01052 clk = clock();
01053 RetValue = Abc_NtkDontCareWindow( p );
01054 p->timeWin += clock() - clk;
01055 if ( !RetValue )
01056 {
01057 p->timeAbort += clock() - clkTotal;
01058 Abc_InfoFill( puTruth, p->nWords );
01059 p->nWinsEmpty++;
01060 return 0;
01061 }
01062
01063 if ( p->fVeryVerbose )
01064 {
01065 printf( " %5d : ", pNode->Id );
01066 printf( "Leaf = %2d ", Vec_PtrSize(p->vLeaves) );
01067 printf( "Root = %2d ", Vec_PtrSize(p->vRoots) );
01068 printf( "Bran = %2d ", Vec_PtrSize(p->vBranches) );
01069 printf( " | " );
01070 }
01071
01072
01073 clk = clock();
01074 Abc_NtkDontCareTransfer( p );
01075 p->timeMiter += clock() - clk;
01076
01077
01078 clk = clock();
01079 nMints = Abc_NtkDontCareSimulateBefore( p, puTruth );
01080 p->timeSim += clock() - clk;
01081 if ( p->fVeryVerbose )
01082 {
01083 printf( "AIG = %5d ", Odc_NodeNum(p) );
01084 printf( "%6.2f %% ", 100.0 * (p->nBits - nMints) / p->nBits );
01085 }
01086
01087
01088 if ( 100.0 * (p->nBits - nMints) / p->nBits < 1.0 * p->nPercCutoff )
01089 {
01090 p->timeAbort += clock() - clkTotal;
01091 if ( p->fVeryVerbose )
01092 printf( "Simulation cutoff.\n" );
01093 Abc_InfoFill( puTruth, p->nWords );
01094 p->nSimsEmpty++;
01095 return 0;
01096 }
01097
01098
01099 clk = clock();
01100 RetValue = Abc_NtkDontCareQuantify( p );
01101 p->timeQuant += clock() - clk;
01102 if ( !RetValue )
01103 {
01104 p->timeAbort += clock() - clkTotal;
01105 if ( p->fVeryVerbose )
01106 printf( "=== Overflow! ===\n" );
01107 Abc_InfoFill( puTruth, p->nWords );
01108 p->nQuantsOver++;
01109 return 0;
01110 }
01111
01112
01113 clk = clock();
01114 Abc_NtkDontCareSimulateSetElem( p );
01115 nMints = Abc_NtkDontCareSimulate( p, puTruth );
01116 p->timeTruth += clock() - clk;
01117 if ( p->fVeryVerbose )
01118 {
01119 printf( "AIG = %5d ", Odc_NodeNum(p) );
01120 printf( "%6.2f %% ", 100.0 * (p->nBits - nMints) / p->nBits );
01121 printf( "\n" );
01122 }
01123 p->timeTotal += clock() - clkTotal;
01124 p->nWinsFinish++;
01125 p->nTotalDcs += (int)(100.0 * (p->nBits - nMints) / p->nBits);
01126 return nMints;
01127 }
01128
01129
01133
01134