00001
00021 #include "abc.h"
00022 #include "cut.h"
00023
00027
00028 #define SCL_LUT_MAX 6 // the maximum LUT size
00029 #define SCL_VARS_MAX 15 // the maximum number of variables
00030 #define SCL_NODE_MAX 1000 // the maximum number of nodes
00031
00032 typedef struct Abc_ManScl_t_ Abc_ManScl_t;
00033 struct Abc_ManScl_t_
00034 {
00035
00036 int nLutSize;
00037 int nCutSizeMax;
00038 int nNodesMax;
00039 int nWords;
00040
00041 Vec_Ptr_t * vLeaves;
00042 Vec_Ptr_t * vVolume;
00043 int pBSet[SCL_VARS_MAX];
00044
00045 unsigned * uTruth;
00046
00047 unsigned ** uVars;
00048 unsigned ** uSims;
00049 unsigned ** uCofs;
00050 };
00051
00052 static Vec_Ptr_t * s_pLeaves = NULL;
00053
00054 static Cut_Man_t * Abc_NtkStartCutManForScl( Abc_Ntk_t * pNtk, int nLutSize );
00055 static Abc_ManScl_t * Abc_ManSclStart( int nLutSize, int nCutSizeMax, int nNodesMax );
00056 static void Abc_ManSclStop( Abc_ManScl_t * p );
00057 static void Abc_NodeLutMap( Cut_Man_t * pManCuts, Abc_Obj_t * pObj );
00058
00059 static Abc_Obj_t * Abc_NodeSuperChoiceLut( Abc_ManScl_t * pManScl, Abc_Obj_t * pObj );
00060 static int Abc_NodeDecomposeStep( Abc_ManScl_t * pManScl );
00061
00065
00077 int Abc_NtkSuperChoiceLut( Abc_Ntk_t * pNtk, int nLutSize, int nCutSizeMax, int fVerbose )
00078 {
00079 ProgressBar * pProgress;
00080 Abc_ManCut_t * pManCut;
00081 Abc_ManScl_t * pManScl;
00082 Cut_Man_t * pManCuts;
00083 Abc_Obj_t * pObj, * pFanin, * pObjTop;
00084 int i, LevelMax, nNodes;
00085 int nNodesTried, nNodesDec, nNodesExist, nNodesUsed;
00086
00087 assert( Abc_NtkIsSopLogic(pNtk) );
00088 if ( nLutSize < 3 || nLutSize > SCL_LUT_MAX )
00089 {
00090 printf( "LUT size (%d) does not belong to the interval: 3 <= LUT size <= %d\n", nLutSize, SCL_LUT_MAX );
00091 return 0;
00092 }
00093 if ( nCutSizeMax <= nLutSize || nCutSizeMax > SCL_VARS_MAX )
00094 {
00095 printf( "Cut size (%d) does not belong to the interval: LUT size (%d) < Cut size <= %d\n", nCutSizeMax, nLutSize, SCL_VARS_MAX );
00096 return 0;
00097 }
00098
00099 assert( nLutSize <= SCL_LUT_MAX );
00100 assert( nCutSizeMax <= SCL_VARS_MAX );
00101 nNodesTried = nNodesDec = nNodesExist = nNodesUsed = 0;
00102
00103
00104 Abc_NtkForEachCi( pNtk, pObj, i )
00105 pObj->Level = 0;
00106
00107
00108
00109
00110 pManScl = Abc_ManSclStart( nLutSize, nCutSizeMax, 1000 );
00111 pManCuts = Abc_NtkStartCutManForScl( pNtk, nLutSize );
00112 pManCut = Abc_NtkManCutStart( nCutSizeMax, 100000, 100000, 100000 );
00113 s_pLeaves = Abc_NtkManCutReadCutSmall( pManCut );
00114 pManScl->vVolume = Abc_NtkManCutReadVisited( pManCut );
00115
00116
00117 nNodes = Abc_NtkObjNumMax(pNtk);
00118 pProgress = Extra_ProgressBarStart( stdout, nNodes );
00119 Abc_NtkForEachObj( pNtk, pObj, i )
00120 {
00121
00122
00123 Extra_ProgressBarUpdate( pProgress, i, NULL );
00124 if ( i >= nNodes )
00125 break;
00126 if ( Abc_ObjFaninNum(pObj) != 2 )
00127 continue;
00128 nNodesTried++;
00129
00130
00131
00132 Abc_NodeLutMap( pManCuts, pObj );
00133
00134 pManScl->vLeaves = Abc_NodeFindCut( pManCut, pObj, 0 );
00135 if ( Vec_PtrSize(pManScl->vLeaves) <= nLutSize )
00136 continue;
00137
00138 if ( Vec_PtrSize(pManScl->vVolume) > SCL_NODE_MAX )
00139 continue;
00140 nNodesDec++;
00141
00142
00143 pObjTop = Abc_NodeSuperChoiceLut( pManScl, pObj );
00144 if ( pObjTop == NULL )
00145 continue;
00146 nNodesExist++;
00147
00148
00149 if ( pObjTop->Level >= pObj->Level )
00150 {
00151 Abc_NtkDeleteObj_rec( pObjTop, 1 );
00152 continue;
00153 }
00154 pObj->Level = pObjTop->Level;
00155 nNodesUsed++;
00156 }
00157 Extra_ProgressBarStop( pProgress );
00158
00159
00160 Abc_ManSclStop( pManScl );
00161 Abc_NtkManCutStop( pManCut );
00162 Cut_ManStop( pManCuts );
00163
00164
00165 LevelMax = 0;
00166 Abc_NtkForEachCo( pNtk, pObj, i )
00167 {
00168 pFanin = Abc_ObjFanin0( pObj );
00169
00170 if ( Abc_ObjFaninNum(pFanin) == 1 )
00171 pFanin = Abc_ObjFanin0( pFanin );
00172
00173 LevelMax = ABC_MAX( LevelMax, (int)pFanin->Level );
00174 }
00175
00176 if ( fVerbose )
00177 printf( "Try = %d. Dec = %d. Exist = %d. Use = %d. SUPER = %d levels of %d-LUTs.\n",
00178 nNodesTried, nNodesDec, nNodesExist, nNodesUsed, LevelMax, nLutSize );
00179
00180
00181
00182
00183 Abc_NtkForEachObj( pNtk, pObj, i )
00184 pObj->pNext = NULL;
00185
00186
00187 if ( !Abc_NtkCheck( pNtk ) )
00188 {
00189 printf( "Abc_NtkSuperChoiceLut: The network check has failed.\n" );
00190 return 0;
00191 }
00192 return 1;
00193 }
00194
00206 void Abc_NodeLutMap( Cut_Man_t * pManCuts, Abc_Obj_t * pObj )
00207 {
00208 Cut_Cut_t * pCut;
00209 Abc_Obj_t * pFanin;
00210 int i, DelayMax;
00211 pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCuts, pObj, 0, 0 );
00212 assert( pCut != NULL );
00213 assert( pObj->Level == 0 );
00214
00215 pObj->Level = ABC_INFINITY;
00216 for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
00217 {
00218 DelayMax = 0;
00219 for ( i = 0; i < (int)pCut->nLeaves; i++ )
00220 {
00221 pFanin = Abc_NtkObj( pObj->pNtk, pCut->pLeaves[i] );
00222
00223 if ( DelayMax < (int)pFanin->Level )
00224 DelayMax = pFanin->Level;
00225 }
00226 if ( (int)pObj->Level > DelayMax )
00227 pObj->Level = DelayMax;
00228 }
00229 assert( pObj->Level < ABC_INFINITY );
00230 pObj->Level++;
00231
00232 }
00233
00245 Cut_Man_t * Abc_NtkStartCutManForScl( Abc_Ntk_t * pNtk, int nLutSize )
00246 {
00247 static Cut_Params_t Params, * pParams = &Params;
00248 Cut_Man_t * pManCut;
00249 Abc_Obj_t * pObj;
00250 int i;
00251
00252 memset( pParams, 0, sizeof(Cut_Params_t) );
00253 pParams->nVarsMax = nLutSize;
00254 pParams->nKeepMax = 500;
00255 pParams->fTruth = 0;
00256 pParams->fFilter = 1;
00257 pParams->fSeq = 0;
00258 pParams->fDrop = 0;
00259 pParams->fVerbose = 0;
00260 pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
00261 pManCut = Cut_ManStart( pParams );
00262 if ( pParams->fDrop )
00263 Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
00264
00265 Abc_NtkForEachCi( pNtk, pObj, i )
00266 if ( Abc_ObjFanoutNum(pObj) > 0 )
00267 Cut_NodeSetTriv( pManCut, pObj->Id );
00268 return pManCut;
00269 }
00270
00282 Abc_ManScl_t * Abc_ManSclStart( int nLutSize, int nCutSizeMax, int nNodesMax )
00283 {
00284 Abc_ManScl_t * p;
00285 int i, k;
00286 assert( sizeof(unsigned) == 4 );
00287 p = ALLOC( Abc_ManScl_t, 1 );
00288 memset( p, 0, sizeof(Abc_ManScl_t) );
00289 p->nLutSize = nLutSize;
00290 p->nCutSizeMax = nCutSizeMax;
00291 p->nNodesMax = nNodesMax;
00292 p->nWords = Extra_TruthWordNum(nCutSizeMax);
00293
00294 p->uVars = (unsigned **)Extra_ArrayAlloc( nCutSizeMax, p->nWords, 4 );
00295 p->uSims = (unsigned **)Extra_ArrayAlloc( nNodesMax, p->nWords, 4 );
00296 p->uCofs = (unsigned **)Extra_ArrayAlloc( 2 << nLutSize, p->nWords, 4 );
00297 memset( p->uVars[0], 0, nCutSizeMax * p->nWords * 4 );
00298
00299 for ( k = 0; k < p->nCutSizeMax; k++ )
00300 for ( i = 0; i < p->nWords * 32; i++ )
00301 if ( i & (1 << k) )
00302 p->uVars[k][i>>5] |= (1 << (i&31));
00303
00304
00305 return p;
00306 }
00307
00319 void Abc_ManSclStop( Abc_ManScl_t * p )
00320 {
00321
00322 free( p->uVars );
00323 free( p->uSims );
00324 free( p->uCofs );
00325 free( p );
00326 }
00327
00328
00340 unsigned * Abc_NodeSuperChoiceTruth( Abc_ManScl_t * pManScl )
00341 {
00342 Abc_Obj_t * pObj;
00343 unsigned * puData0, * puData1, * puData;
00344 char * pSop;
00345 int i, k;
00346
00347 Vec_PtrForEachEntry( pManScl->vLeaves, pObj, i )
00348 pObj->pNext = (Abc_Obj_t *)pManScl->uVars[i];
00349
00350 Vec_PtrForEachEntry( pManScl->vVolume, pObj, i )
00351 {
00352
00353 pObj->pNext = (Abc_Obj_t *)pManScl->uSims[i];
00354
00355 puData = (unsigned *)pObj->pNext;
00356 puData0 = (unsigned *)Abc_ObjFanin0(pObj)->pNext;
00357 puData1 = (unsigned *)Abc_ObjFanin1(pObj)->pNext;
00358
00359 pSop = pObj->pData;
00360 if ( pSop[0] == '0' && pSop[1] == '0' )
00361 for ( k = 0; k < pManScl->nWords; k++ )
00362 puData[k] = ~puData0[k] & ~puData1[k];
00363 else if ( pSop[0] == '0' )
00364 for ( k = 0; k < pManScl->nWords; k++ )
00365 puData[k] = ~puData0[k] & puData1[k];
00366 else if ( pSop[1] == '0' )
00367 for ( k = 0; k < pManScl->nWords; k++ )
00368 puData[k] = puData0[k] & ~puData1[k];
00369 else
00370 for ( k = 0; k < pManScl->nWords; k++ )
00371 puData[k] = puData0[k] & puData1[k];
00372 }
00373 return puData;
00374 }
00375
00387 void Abc_NodeSuperChoiceCollect2_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vVolume )
00388 {
00389 if ( pObj->fMarkC )
00390 return;
00391 pObj->fMarkC = 1;
00392 assert( Abc_ObjFaninNum(pObj) == 2 );
00393 Abc_NodeSuperChoiceCollect2_rec( Abc_ObjFanin0(pObj), vVolume );
00394 Abc_NodeSuperChoiceCollect2_rec( Abc_ObjFanin1(pObj), vVolume );
00395 Vec_PtrPush( vVolume, pObj );
00396 }
00397
00409 void Abc_NodeSuperChoiceCollect2( Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVolume )
00410 {
00411 Abc_Obj_t * pObj;
00412 int i;
00413 Vec_PtrForEachEntry( vLeaves, pObj, i )
00414 pObj->fMarkC = 1;
00415 Vec_PtrClear( vVolume );
00416 Abc_NodeSuperChoiceCollect2_rec( pRoot, vVolume );
00417 Vec_PtrForEachEntry( vLeaves, pObj, i )
00418 pObj->fMarkC = 0;
00419 Vec_PtrForEachEntry( vVolume, pObj, i )
00420 pObj->fMarkC = 0;
00421 }
00422
00434 void Abc_NodeSuperChoiceCollect_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVolume )
00435 {
00436 if ( pObj->fMarkB )
00437 {
00438 Vec_PtrPush( vLeaves, pObj );
00439 pObj->fMarkB = 0;
00440 }
00441 if ( pObj->fMarkC )
00442 return;
00443 pObj->fMarkC = 1;
00444 assert( Abc_ObjFaninNum(pObj) == 2 );
00445 Abc_NodeSuperChoiceCollect_rec( Abc_ObjFanin0(pObj), vLeaves, vVolume );
00446 Abc_NodeSuperChoiceCollect_rec( Abc_ObjFanin1(pObj), vLeaves, vVolume );
00447 Vec_PtrPush( vVolume, pObj );
00448 }
00449
00461 void Abc_NodeSuperChoiceCollect( Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVolume )
00462 {
00463 Abc_Obj_t * pObj;
00464 int i, nLeaves;
00465 nLeaves = Vec_PtrSize(vLeaves);
00466 Vec_PtrForEachEntry( vLeaves, pObj, i )
00467 pObj->fMarkB = pObj->fMarkC = 1;
00468 Vec_PtrClear( vVolume );
00469 Vec_PtrClear( vLeaves );
00470 Abc_NodeSuperChoiceCollect_rec( pRoot, vLeaves, vVolume );
00471 assert( Vec_PtrSize(vLeaves) == nLeaves );
00472 Vec_PtrForEachEntry( vLeaves, pObj, i )
00473 pObj->fMarkC = 0;
00474 Vec_PtrForEachEntry( vVolume, pObj, i )
00475 pObj->fMarkC = 0;
00476 }
00477
00489 void Abc_NodeLeavesRemove( Vec_Ptr_t * vLeaves, unsigned uPhase, int nVars )
00490 {
00491 int i;
00492 for ( i = nVars - 1; i >= 0; i-- )
00493 if ( uPhase & (1 << i) )
00494 Vec_PtrRemove( vLeaves, Vec_PtrEntry(vLeaves, i) );
00495 }
00496
00508 int Abc_NodeGetLevel( Abc_Obj_t * pObj )
00509 {
00510 Abc_Obj_t * pFanin;
00511 int i, Level;
00512 Level = 0;
00513 Abc_ObjForEachFanin( pObj, pFanin, i )
00514 Level = ABC_MAX( Level, (int)pFanin->Level );
00515 return Level + 1;
00516 }
00517
00529 Abc_Obj_t * Abc_NodeSuperChoiceLut( Abc_ManScl_t * p, Abc_Obj_t * pObj )
00530 {
00531 Abc_Obj_t * pFanin, * pObjNew;
00532 int i, nVars, uSupport, nSuppVars;
00533
00534 Abc_NodeSuperChoiceCollect2( pObj, p->vLeaves, p->vVolume );
00535 assert( Vec_PtrEntryLast(p->vVolume) == pObj );
00536
00537 p->uTruth = Abc_NodeSuperChoiceTruth( p );
00538
00539 nVars = Vec_PtrSize(p->vLeaves);
00540 uSupport = Extra_TruthSupport(p->uTruth, nVars);
00541 nSuppVars = Extra_WordCountOnes(uSupport);
00542 assert( nSuppVars <= nVars );
00543 if ( nSuppVars == 0 )
00544 {
00545 pObj->Level = 0;
00546 return NULL;
00547 }
00548 if ( nSuppVars == 1 )
00549 {
00550
00551 for ( i = 0; i < nVars; i++ )
00552 if ( uSupport & (1 << i) )
00553 break;
00554 assert( i < nVars );
00555 pFanin = Vec_PtrEntry( p->vLeaves, i );
00556 pObj->Level = pFanin->Level;
00557 return NULL;
00558 }
00559
00560 if ( nSuppVars != nVars )
00561 {
00562 Extra_TruthShrink( p->uCofs[0], p->uTruth, nSuppVars, nVars, uSupport );
00563 Extra_TruthCopy( p->uTruth, p->uCofs[0], nVars );
00564 Abc_NodeLeavesRemove( p->vLeaves, ((1 << nVars) - 1) & ~uSupport, nVars );
00565 }
00566
00567
00568 while ( Vec_PtrSize(p->vLeaves) > p->nLutSize )
00569 if ( !Abc_NodeDecomposeStep( p ) )
00570 {
00571 Vec_PtrForEachEntry( p->vLeaves, pFanin, i )
00572 if ( Abc_ObjIsNode(pFanin) && Abc_ObjFanoutNum(pFanin) == 0 )
00573 Abc_NtkDeleteObj_rec( pFanin, 1 );
00574 return NULL;
00575 }
00576
00577 pObjNew = Abc_NtkCreateNode( pObj->pNtk );
00578 Vec_PtrForEachEntry( p->vLeaves, pFanin, i )
00579 Abc_ObjAddFanin( pObjNew, pFanin );
00580
00581 pObjNew->pData = Abc_SopCreateFromTruth( pObj->pNtk->pManFunc, Vec_PtrSize(p->vLeaves), p->uTruth );
00582 pObjNew->Level = Abc_NodeGetLevel( pObjNew );
00583 return pObjNew;
00584 }
00585
00597 int Abc_NodeCompareLevelsInc( int * pp1, int * pp2 )
00598 {
00599 Abc_Obj_t * pNode1, * pNode2;
00600 pNode1 = Vec_PtrEntry(s_pLeaves, *pp1);
00601 pNode2 = Vec_PtrEntry(s_pLeaves, *pp2);
00602 if ( pNode1->Level < pNode2->Level )
00603 return -1;
00604 if ( pNode1->Level > pNode2->Level )
00605 return 1;
00606 return 0;
00607 }
00608
00620 void Abc_NodeDecomposeSort( Abc_Obj_t ** pLeaves, int nVars, int * pBSet, int nLutSize )
00621 {
00622 Abc_Obj_t * pTemp[SCL_VARS_MAX];
00623 int i, k, kBest, LevelMin;
00624 assert( nLutSize < nVars );
00625 assert( nVars <= SCL_VARS_MAX );
00626
00627
00628 for ( i = 0; i < nVars; i++ )
00629 {
00630 pTemp[i] = pLeaves[i];
00631
00632 }
00633
00634
00635 for ( i = 0; i < nLutSize; i++ )
00636 {
00637 kBest = -1;
00638 LevelMin = ABC_INFINITY;
00639 for ( k = 0; k < nVars; k++ )
00640 if ( pTemp[k] && LevelMin > (int)pTemp[k]->Level )
00641 {
00642 LevelMin = pTemp[k]->Level;
00643 kBest = k;
00644 }
00645 pBSet[i] = kBest;
00646 pTemp[kBest] = NULL;
00647 }
00648 }
00649
00661 int Abc_NodeDecomposeStep( Abc_ManScl_t * p )
00662 {
00663 static char pCofClasses[1<<SCL_LUT_MAX][1<<SCL_LUT_MAX];
00664 static char nCofClasses[1<<SCL_LUT_MAX];
00665 Abc_Ntk_t * pNtk;
00666 Abc_Obj_t * pObjNew, * pFanin, * pNodesNew[SCL_LUT_MAX];
00667 unsigned * pTruthCof, * pTruthClass, * pTruth, uPhase;
00668 int i, k, c, v, w, nVars, nVarsNew, nClasses, nCofs;
00669
00670 pNtk = ((Abc_Obj_t *)Vec_PtrEntry(p->vLeaves, 0))->pNtk;
00671
00672 nVars = Vec_PtrSize(p->vLeaves);
00673 assert( nVars > p->nLutSize );
00674
00675
00676
00677
00678
00679
00680 Abc_NodeDecomposeSort( (Abc_Obj_t **)Vec_PtrArray(p->vLeaves), Vec_PtrSize(p->vLeaves), p->pBSet, p->nLutSize );
00681 assert( ((Abc_Obj_t *)Vec_PtrEntry(p->vLeaves, p->pBSet[0]))->Level <=
00682 ((Abc_Obj_t *)Vec_PtrEntry(p->vLeaves, p->pBSet[1]))->Level );
00683
00684 Extra_TruthCopy( p->uCofs[1], p->uTruth, nVars );
00685 c = 2;
00686 for ( v = 0; v < p->nLutSize; v++ )
00687 for ( k = 0; k < (1<<v); k++ )
00688 {
00689 Extra_TruthCopy( p->uCofs[c], p->uCofs[c/2], nVars );
00690 Extra_TruthCopy( p->uCofs[c+1], p->uCofs[c/2], nVars );
00691 Extra_TruthCofactor0( p->uCofs[c], nVars, p->pBSet[v] );
00692 Extra_TruthCofactor1( p->uCofs[c+1], nVars, p->pBSet[v] );
00693 c += 2;
00694 }
00695 assert( c == (2 << p->nLutSize) );
00696
00697 nClasses = 0;
00698 nCofs = (1 << p->nLutSize);
00699 for ( i = 0; i < nCofs; i++ )
00700 {
00701 pTruthCof = p->uCofs[ nCofs + i ];
00702 for ( k = 0; k < nClasses; k++ )
00703 {
00704 pTruthClass = p->uCofs[ nCofs + pCofClasses[k][0] ];
00705 if ( Extra_TruthIsEqual( pTruthCof, pTruthClass, nVars ) )
00706 {
00707 pCofClasses[k][ nCofClasses[k]++ ] = i;
00708 break;
00709 }
00710 }
00711 if ( k != nClasses )
00712 continue;
00713
00714 pCofClasses[nClasses][0] = i;
00715 nCofClasses[nClasses] = 1;
00716 nClasses++;
00717 if ( nClasses > nCofs/2 )
00718 return 0;
00719 }
00720
00721 nVarsNew = Extra_Base2Log( nClasses );
00722 assert( nVarsNew < p->nLutSize );
00723
00724
00725 Extra_TruthClear( p->uTruth, nVars );
00726 for ( k = 0; k < nClasses; k++ )
00727 {
00728 pTruthClass = p->uCofs[ nCofs + pCofClasses[k][0] ];
00729 for ( v = 0; v < nVarsNew; v++ )
00730 if ( k & (1 << v) )
00731 Extra_TruthAnd( pTruthClass, pTruthClass, p->uVars[p->pBSet[v]], nVars );
00732 else
00733 Extra_TruthSharp( pTruthClass, pTruthClass, p->uVars[p->pBSet[v]], nVars );
00734 Extra_TruthOr( p->uTruth, p->uTruth, pTruthClass, nVars );
00735 }
00736
00737 pTruth = p->uCofs[0];
00738 for ( v = 0; v < nVarsNew; v++ )
00739 {
00740 Extra_TruthClear( pTruth, p->nLutSize );
00741 for ( k = 0; k < nClasses; k++ )
00742 if ( k & (1 << v) )
00743 for ( i = 0; i < nCofClasses[k]; i++ )
00744 {
00745 pTruthCof = p->uCofs[1];
00746 Extra_TruthFill( pTruthCof, p->nLutSize );
00747 for ( w = 0; w < p->nLutSize; w++ )
00748 if ( pCofClasses[k][i] & (1 << (p->nLutSize-1-w)) )
00749 Extra_TruthAnd( pTruthCof, pTruthCof, p->uVars[w], p->nLutSize );
00750 else
00751 Extra_TruthSharp( pTruthCof, pTruthCof, p->uVars[w], p->nLutSize );
00752 Extra_TruthOr( pTruth, pTruth, pTruthCof, p->nLutSize );
00753 }
00754
00755 pObjNew = Abc_NtkCreateNode( pNtk );
00756 for ( i = 0; i < p->nLutSize; i++ )
00757 {
00758 pFanin = Vec_PtrEntry( p->vLeaves, p->pBSet[i] );
00759 Abc_ObjAddFanin( pObjNew, pFanin );
00760 }
00761
00762 pObjNew->pData = Abc_SopCreateFromTruth( pNtk->pManFunc, p->nLutSize, pTruth );
00763 pObjNew->Level = Abc_NodeGetLevel( pObjNew );
00764 pNodesNew[v] = pObjNew;
00765 }
00766
00767 for ( v = 0; v < nVarsNew; v++ )
00768 Vec_PtrWriteEntry( p->vLeaves, p->pBSet[v], pNodesNew[v] );
00769
00770 uPhase = 0;
00771 for ( v = nVarsNew; v < p->nLutSize; v++ )
00772 uPhase |= (1 << p->pBSet[v]);
00773
00774 Abc_NodeLeavesRemove( p->vLeaves, uPhase, nVars );
00775
00776 Extra_TruthShrink( p->uCofs[0], p->uTruth, nVars - p->nLutSize + nVarsNew, nVars, ((1 << nVars) - 1) & ~uPhase );
00777 Extra_TruthCopy( p->uTruth, p->uCofs[0], nVars );
00778 assert( !Extra_TruthVarInSupport( p->uTruth, nVars, nVars - p->nLutSize + nVarsNew ) );
00779 return 1;
00780 }
00781
00785
00786