00001
00021 #include "abc.h"
00022 #include "dec.h"
00023
00027
00028 #define ABC_RS_DIV1_MAX 150 // the max number of divisors to consider
00029 #define ABC_RS_DIV2_MAX 500 // the max number of pair-wise divisors to consider
00030
00031 typedef struct Abc_ManRes_t_ Abc_ManRes_t;
00032 struct Abc_ManRes_t_
00033 {
00034
00035 int nLeavesMax;
00036 int nDivsMax;
00037
00038 Abc_Obj_t * pRoot;
00039 int nLeaves;
00040 int nDivs;
00041 int nMffc;
00042 int nLastGain;
00043 Vec_Ptr_t * vDivs;
00044
00045 int nBits;
00046 int nWords;
00047 Vec_Ptr_t * vSims;
00048 unsigned * pInfo;
00049
00050 unsigned * pCareSet;
00051
00052 Vec_Ptr_t * vDivs1UP;
00053 Vec_Ptr_t * vDivs1UN;
00054 Vec_Ptr_t * vDivs1B;
00055 Vec_Ptr_t * vDivs2UP0;
00056 Vec_Ptr_t * vDivs2UP1;
00057 Vec_Ptr_t * vDivs2UN0;
00058 Vec_Ptr_t * vDivs2UN1;
00059
00060 Vec_Ptr_t * vTemp;
00061
00062 int timeCut;
00063 int timeTruth;
00064 int timeRes;
00065 int timeDiv;
00066 int timeMffc;
00067 int timeSim;
00068 int timeRes1;
00069 int timeResD;
00070 int timeRes2;
00071 int timeRes3;
00072 int timeNtk;
00073 int timeTotal;
00074
00075 int nUsedNodeC;
00076 int nUsedNode0;
00077 int nUsedNode1Or;
00078 int nUsedNode1And;
00079 int nUsedNode2Or;
00080 int nUsedNode2And;
00081 int nUsedNode2OrAnd;
00082 int nUsedNode2AndOr;
00083 int nUsedNode3OrAnd;
00084 int nUsedNode3AndOr;
00085 int nUsedNodeTotal;
00086 int nTotalDivs;
00087 int nTotalLeaves;
00088 int nTotalGain;
00089 int nNodesBeg;
00090 int nNodesEnd;
00091 };
00092
00093
00094 static Abc_ManRes_t* Abc_ManResubStart( int nLeavesMax, int nDivsMax );
00095 static void Abc_ManResubStop( Abc_ManRes_t * p );
00096 static Dec_Graph_t * Abc_ManResubEval( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int nSteps, bool fUpdateLevel, int fVerbose );
00097 static void Abc_ManResubCleanup( Abc_ManRes_t * p );
00098 static void Abc_ManResubPrint( Abc_ManRes_t * p );
00099
00100
00101 static int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required );
00102 static void Abc_ManResubSimulate( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords );
00103 static void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves );
00104
00105 static void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required );
00106 static void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required );
00107 static Dec_Graph_t * Abc_ManResubQuit( Abc_ManRes_t * p );
00108 static Dec_Graph_t * Abc_ManResubDivs0( Abc_ManRes_t * p );
00109 static Dec_Graph_t * Abc_ManResubDivs1( Abc_ManRes_t * p, int Required );
00110 static Dec_Graph_t * Abc_ManResubDivs12( Abc_ManRes_t * p, int Required );
00111 static Dec_Graph_t * Abc_ManResubDivs2( Abc_ManRes_t * p, int Required );
00112 static Dec_Graph_t * Abc_ManResubDivs3( Abc_ManRes_t * p, int Required );
00113
00114 static Vec_Ptr_t * Abc_CutFactorLarge( Abc_Obj_t * pNode, int nLeavesMax );
00115 static int Abc_CutVolumeCheck( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves );
00116
00117
00118 extern void * Abc_NtkDontCareAlloc( int nVarsMax, int nLevels, int fVerbose, int fVeryVerbose );
00119 extern void Abc_NtkDontCareClear( void * p );
00120 extern void Abc_NtkDontCareFree( void * p );
00121 extern int Abc_NtkDontCareCompute( void * p, Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, unsigned * puTruth );
00122
00123 extern int s_ResubTime;
00124
00128
00140 int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, int nLevelsOdc, bool fUpdateLevel, bool fVerbose, bool fVeryVerbose )
00141 {
00142 ProgressBar * pProgress;
00143 Abc_ManRes_t * pManRes;
00144 Abc_ManCut_t * pManCut;
00145 void * pManOdc = NULL;
00146 Dec_Graph_t * pFForm;
00147 Vec_Ptr_t * vLeaves;
00148 Abc_Obj_t * pNode;
00149 int clk, clkStart = clock();
00150 int i, nNodes;
00151
00152 assert( Abc_NtkIsStrash(pNtk) );
00153
00154
00155 Abc_AigCleanup(pNtk->pManFunc);
00156
00157 pManCut = Abc_NtkManCutStart( nCutMax, 100000, 100000, 100000 );
00158 pManRes = Abc_ManResubStart( nCutMax, ABC_RS_DIV1_MAX );
00159 if ( nLevelsOdc > 0 )
00160 pManOdc = Abc_NtkDontCareAlloc( nCutMax, nLevelsOdc, fVerbose, fVeryVerbose );
00161
00162
00163 if ( fUpdateLevel )
00164 Abc_NtkStartReverseLevels( pNtk, 0 );
00165
00166 if ( Abc_NtkLatchNum(pNtk) )
00167 Abc_NtkForEachLatch(pNtk, pNode, i)
00168 pNode->pNext = pNode->pData;
00169
00170
00171 pManRes->nNodesBeg = Abc_NtkNodeNum(pNtk);
00172 nNodes = Abc_NtkObjNumMax(pNtk);
00173 pProgress = Extra_ProgressBarStart( stdout, nNodes );
00174 Abc_NtkForEachNode( pNtk, pNode, i )
00175 {
00176 Extra_ProgressBarUpdate( pProgress, i, NULL );
00177
00178
00179
00180
00181 if ( Abc_NodeIsPersistant(pNode) )
00182 continue;
00183
00184 if ( Abc_ObjFanoutNum(pNode) > 1000 )
00185 continue;
00186
00187 if ( i >= nNodes )
00188 break;
00189
00190
00191 clk = clock();
00192 vLeaves = Abc_NodeFindCut( pManCut, pNode, 0 );
00193
00194 pManRes->timeCut += clock() - clk;
00195
00196
00197
00198
00199
00200
00201
00202 if ( pManOdc )
00203 {
00204 clk = clock();
00205 Abc_NtkDontCareClear( pManOdc );
00206 Abc_NtkDontCareCompute( pManOdc, pNode, vLeaves, pManRes->pCareSet );
00207 pManRes->timeTruth += clock() - clk;
00208 }
00209
00210
00211 clk = clock();
00212 pFForm = Abc_ManResubEval( pManRes, pNode, vLeaves, nStepsMax, fUpdateLevel, fVerbose );
00213
00214
00215 pManRes->timeRes += clock() - clk;
00216 if ( pFForm == NULL )
00217 continue;
00218 pManRes->nTotalGain += pManRes->nLastGain;
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 clk = clock();
00230 Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRes->nLastGain );
00231 pManRes->timeNtk += clock() - clk;
00232 Dec_GraphFree( pFForm );
00233 }
00234 Extra_ProgressBarStop( pProgress );
00235 pManRes->timeTotal = clock() - clkStart;
00236 pManRes->nNodesEnd = Abc_NtkNodeNum(pNtk);
00237
00238
00239 if ( fVerbose )
00240 Abc_ManResubPrint( pManRes );
00241
00242
00243 Abc_ManResubStop( pManRes );
00244 Abc_NtkManCutStop( pManCut );
00245 if ( pManOdc ) Abc_NtkDontCareFree( pManOdc );
00246
00247
00248 Abc_NtkForEachObj( pNtk, pNode, i )
00249 pNode->pData = NULL;
00250
00251 if ( Abc_NtkLatchNum(pNtk) )
00252 Abc_NtkForEachLatch(pNtk, pNode, i)
00253 pNode->pData = pNode->pNext, pNode->pNext = NULL;
00254
00255
00256 Abc_NtkReassignIds( pNtk );
00257
00258
00259 if ( fUpdateLevel )
00260 Abc_NtkStopReverseLevels( pNtk );
00261 else
00262 Abc_NtkLevel( pNtk );
00263
00264 if ( !Abc_NtkCheck( pNtk ) )
00265 {
00266 printf( "Abc_NtkRefactor: The network check has failed.\n" );
00267 return 0;
00268 }
00269 s_ResubTime = clock() - clkStart;
00270 return 1;
00271 }
00272
00273
00274
00275
00287 Abc_ManRes_t * Abc_ManResubStart( int nLeavesMax, int nDivsMax )
00288 {
00289 Abc_ManRes_t * p;
00290 unsigned * pData;
00291 int i, k;
00292 assert( sizeof(unsigned) == 4 );
00293 p = ALLOC( Abc_ManRes_t, 1 );
00294 memset( p, 0, sizeof(Abc_ManRes_t) );
00295 p->nLeavesMax = nLeavesMax;
00296 p->nDivsMax = nDivsMax;
00297 p->vDivs = Vec_PtrAlloc( p->nDivsMax );
00298
00299 p->nBits = (1 << p->nLeavesMax);
00300 p->nWords = (p->nBits <= 32)? 1 : (p->nBits / 32);
00301 p->pInfo = ALLOC( unsigned, p->nWords * (p->nDivsMax + 1) );
00302 memset( p->pInfo, 0, sizeof(unsigned) * p->nWords * p->nLeavesMax );
00303 p->vSims = Vec_PtrAlloc( p->nDivsMax );
00304 for ( i = 0; i < p->nDivsMax; i++ )
00305 Vec_PtrPush( p->vSims, p->pInfo + i * p->nWords );
00306
00307 p->pCareSet = p->pInfo + p->nDivsMax * p->nWords;
00308 Abc_InfoFill( p->pCareSet, p->nWords );
00309
00310 for ( k = 0; k < p->nLeavesMax; k++ )
00311 {
00312 pData = p->vSims->pArray[k];
00313 for ( i = 0; i < p->nBits; i++ )
00314 if ( i & (1 << k) )
00315 pData[i>>5] |= (1 << (i&31));
00316 }
00317
00318 p->vDivs1UP = Vec_PtrAlloc( p->nDivsMax );
00319 p->vDivs1UN = Vec_PtrAlloc( p->nDivsMax );
00320 p->vDivs1B = Vec_PtrAlloc( p->nDivsMax );
00321 p->vDivs2UP0 = Vec_PtrAlloc( p->nDivsMax );
00322 p->vDivs2UP1 = Vec_PtrAlloc( p->nDivsMax );
00323 p->vDivs2UN0 = Vec_PtrAlloc( p->nDivsMax );
00324 p->vDivs2UN1 = Vec_PtrAlloc( p->nDivsMax );
00325 p->vTemp = Vec_PtrAlloc( p->nDivsMax );
00326 return p;
00327 }
00328
00340 void Abc_ManResubStop( Abc_ManRes_t * p )
00341 {
00342 Vec_PtrFree( p->vDivs );
00343 Vec_PtrFree( p->vSims );
00344 Vec_PtrFree( p->vDivs1UP );
00345 Vec_PtrFree( p->vDivs1UN );
00346 Vec_PtrFree( p->vDivs1B );
00347 Vec_PtrFree( p->vDivs2UP0 );
00348 Vec_PtrFree( p->vDivs2UP1 );
00349 Vec_PtrFree( p->vDivs2UN0 );
00350 Vec_PtrFree( p->vDivs2UN1 );
00351 Vec_PtrFree( p->vTemp );
00352 free( p->pInfo );
00353 free( p );
00354 }
00355
00367 void Abc_ManResubPrint( Abc_ManRes_t * p )
00368 {
00369 printf( "Used constants = %6d. ", p->nUsedNodeC ); PRT( "Cuts ", p->timeCut );
00370 printf( "Used replacements = %6d. ", p->nUsedNode0 ); PRT( "Resub ", p->timeRes );
00371 printf( "Used single ORs = %6d. ", p->nUsedNode1Or ); PRT( " Div ", p->timeDiv );
00372 printf( "Used single ANDs = %6d. ", p->nUsedNode1And ); PRT( " Mffc ", p->timeMffc );
00373 printf( "Used double ORs = %6d. ", p->nUsedNode2Or ); PRT( " Sim ", p->timeSim );
00374 printf( "Used double ANDs = %6d. ", p->nUsedNode2And ); PRT( " 1 ", p->timeRes1 );
00375 printf( "Used OR-AND = %6d. ", p->nUsedNode2OrAnd ); PRT( " D ", p->timeResD );
00376 printf( "Used AND-OR = %6d. ", p->nUsedNode2AndOr ); PRT( " 2 ", p->timeRes2 );
00377 printf( "Used OR-2ANDs = %6d. ", p->nUsedNode3OrAnd ); PRT( "Truth ", p->timeTruth );
00378 printf( "Used AND-2ORs = %6d. ", p->nUsedNode3AndOr ); PRT( "AIG ", p->timeNtk );
00379 printf( "TOTAL = %6d. ", p->nUsedNodeC +
00380 p->nUsedNode0 +
00381 p->nUsedNode1Or +
00382 p->nUsedNode1And +
00383 p->nUsedNode2Or +
00384 p->nUsedNode2And +
00385 p->nUsedNode2OrAnd +
00386 p->nUsedNode2AndOr +
00387 p->nUsedNode3OrAnd +
00388 p->nUsedNode3AndOr
00389 ); PRT( "TOTAL ", p->timeTotal );
00390 printf( "Total leaves = %8d.\n", p->nTotalLeaves );
00391 printf( "Total divisors = %8d.\n", p->nTotalDivs );
00392
00393 printf( "Gain = %8d. (%6.2f %%).\n", p->nNodesBeg-p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg );
00394 }
00395
00396
00408 void Abc_ManResubCollectDivs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vInternal )
00409 {
00410
00411 if ( Abc_NodeIsTravIdCurrent(pNode) )
00412 return;
00413 Abc_NodeSetTravIdCurrent(pNode);
00414
00415 Abc_ManResubCollectDivs_rec( Abc_ObjFanin0(pNode), vInternal );
00416 Abc_ManResubCollectDivs_rec( Abc_ObjFanin1(pNode), vInternal );
00417
00418 if ( pNode->fMarkA == 0 )
00419 Vec_PtrPush( vInternal, pNode );
00420 }
00421
00433 int Abc_ManResubCollectDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int Required )
00434 {
00435 Abc_Obj_t * pNode, * pFanout;
00436 int i, k, Limit, Counter;
00437
00438 Vec_PtrClear( p->vDivs1UP );
00439 Vec_PtrClear( p->vDivs1UN );
00440 Vec_PtrClear( p->vDivs1B );
00441
00442
00443 Vec_PtrClear( p->vDivs );
00444 Abc_NtkIncrementTravId( pRoot->pNtk );
00445 Vec_PtrForEachEntry( vLeaves, pNode, i )
00446 {
00447 Vec_PtrPush( p->vDivs, pNode );
00448 Abc_NodeSetTravIdCurrent( pNode );
00449 }
00450
00451
00452 Vec_PtrForEachEntry( p->vTemp, pNode, i )
00453 pNode->fMarkA = 1;
00454
00455 Abc_ManResubCollectDivs_rec( pRoot, p->vDivs );
00456
00457 Vec_PtrForEachEntry( p->vTemp, pNode, i )
00458 pNode->fMarkA = 0;
00459
00460
00461 if ( Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) + Vec_PtrSize(p->vTemp) >= Vec_PtrSize(p->vSims) - p->nLeavesMax )
00462 return 0;
00463
00464
00465 Limit = Vec_PtrSize(p->vSims) - p->nLeavesMax - (Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) + Vec_PtrSize(p->vTemp));
00466
00467
00468 Counter = 0;
00469 Vec_PtrForEachEntry( p->vDivs, pNode, i )
00470 {
00471 if ( Abc_ObjFanoutNum(pNode) > 100 )
00472 {
00473
00474 continue;
00475 }
00476
00477 Abc_ObjForEachFanout( pNode, pFanout, k )
00478 {
00479 if ( Abc_NodeIsTravIdCurrent(pFanout) || Abc_ObjIsCo(pFanout) || (int)pFanout->Level > Required )
00480 continue;
00481 if ( Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pFanout)) && Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pFanout)) )
00482 {
00483 if ( Abc_ObjFanin0(pFanout) == pRoot || Abc_ObjFanin1(pFanout) == pRoot )
00484 continue;
00485 Vec_PtrPush( p->vDivs, pFanout );
00486 Abc_NodeSetTravIdCurrent( pFanout );
00487
00488 if ( ++Counter == Limit )
00489 goto Quits;
00490 }
00491 }
00492 }
00493
00494 Quits :
00495
00496 p->nDivs = Vec_PtrSize(p->vDivs);
00497
00498
00499 Vec_PtrForEachEntry( p->vTemp, pNode, i )
00500 Vec_PtrPush( p->vDivs, pNode );
00501 assert( pRoot == Vec_PtrEntryLast(p->vDivs) );
00502
00503 assert( Vec_PtrSize(p->vDivs) - Vec_PtrSize(vLeaves) <= Vec_PtrSize(p->vSims) - p->nLeavesMax );
00504 return 1;
00505 }
00506
00518 void Abc_ManResubPrintDivs( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves )
00519 {
00520 Abc_Obj_t * pFanin, * pNode;
00521 int i, k;
00522
00523 Vec_PtrForEachEntry( p->vDivs, pNode, i )
00524 {
00525 if ( i < Vec_PtrSize(vLeaves) )
00526 {
00527 printf( "%6d : %c\n", pNode->Id, 'a'+i );
00528 continue;
00529 }
00530 printf( "%6d : %2d = ", pNode->Id, i );
00531
00532 Vec_PtrForEachEntry( p->vDivs, pFanin, k )
00533 if ( Abc_ObjFanin0(pNode) == pFanin )
00534 break;
00535 if ( k < Vec_PtrSize(vLeaves) )
00536 printf( "%c", 'a' + k );
00537 else
00538 printf( "%d", k );
00539 printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" );
00540
00541 Vec_PtrForEachEntry( p->vDivs, pFanin, k )
00542 if ( Abc_ObjFanin1(pNode) == pFanin )
00543 break;
00544 if ( k < Vec_PtrSize(vLeaves) )
00545 printf( "%c", 'a' + k );
00546 else
00547 printf( "%d", k );
00548 printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" );
00549 if ( pNode == pRoot )
00550 printf( " root" );
00551 printf( "\n" );
00552 }
00553 printf( "\n" );
00554 }
00555
00556
00568 void Abc_ManResubSimulate( Vec_Ptr_t * vDivs, int nLeaves, Vec_Ptr_t * vSims, int nLeavesMax, int nWords )
00569 {
00570 Abc_Obj_t * pObj;
00571 unsigned * puData0, * puData1, * puData;
00572 int i, k;
00573 assert( Vec_PtrSize(vDivs) - nLeaves <= Vec_PtrSize(vSims) - nLeavesMax );
00574
00575 Vec_PtrForEachEntry( vDivs, pObj, i )
00576 {
00577 if ( i < nLeaves )
00578 {
00579 pObj->pData = Vec_PtrEntry( vSims, i );
00580 continue;
00581 }
00582
00583 pObj->pData = Vec_PtrEntry( vSims, i - nLeaves + nLeavesMax );
00584
00585 puData = pObj->pData;
00586 puData0 = Abc_ObjFanin0(pObj)->pData;
00587 puData1 = Abc_ObjFanin1(pObj)->pData;
00588
00589 if ( Abc_ObjFaninC0(pObj) && Abc_ObjFaninC1(pObj) )
00590 for ( k = 0; k < nWords; k++ )
00591 puData[k] = ~puData0[k] & ~puData1[k];
00592 else if ( Abc_ObjFaninC0(pObj) )
00593 for ( k = 0; k < nWords; k++ )
00594 puData[k] = ~puData0[k] & puData1[k];
00595 else if ( Abc_ObjFaninC1(pObj) )
00596 for ( k = 0; k < nWords; k++ )
00597 puData[k] = puData0[k] & ~puData1[k];
00598 else
00599 for ( k = 0; k < nWords; k++ )
00600 puData[k] = puData0[k] & puData1[k];
00601 }
00602
00603 Vec_PtrForEachEntry( vDivs, pObj, i )
00604 {
00605 puData = pObj->pData;
00606 pObj->fPhase = (puData[0] & 1);
00607 if ( pObj->fPhase )
00608 for ( k = 0; k < nWords; k++ )
00609 puData[k] = ~puData[k];
00610 }
00611 }
00612
00613
00625 Dec_Graph_t * Abc_ManResubQuit0( Abc_Obj_t * pRoot, Abc_Obj_t * pObj )
00626 {
00627 Dec_Graph_t * pGraph;
00628 Dec_Edge_t eRoot;
00629 pGraph = Dec_GraphCreate( 1 );
00630 Dec_GraphNode( pGraph, 0 )->pFunc = pObj;
00631 eRoot = Dec_EdgeCreate( 0, pObj->fPhase );
00632 Dec_GraphSetRoot( pGraph, eRoot );
00633 if ( pRoot->fPhase )
00634 Dec_GraphComplement( pGraph );
00635 return pGraph;
00636 }
00637
00649 Dec_Graph_t * Abc_ManResubQuit1( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, int fOrGate )
00650 {
00651 Dec_Graph_t * pGraph;
00652 Dec_Edge_t eRoot, eNode0, eNode1;
00653 assert( pObj0 != pObj1 );
00654 assert( !Abc_ObjIsComplement(pObj0) );
00655 assert( !Abc_ObjIsComplement(pObj1) );
00656 pGraph = Dec_GraphCreate( 2 );
00657 Dec_GraphNode( pGraph, 0 )->pFunc = pObj0;
00658 Dec_GraphNode( pGraph, 1 )->pFunc = pObj1;
00659 eNode0 = Dec_EdgeCreate( 0, pObj0->fPhase );
00660 eNode1 = Dec_EdgeCreate( 1, pObj1->fPhase );
00661 if ( fOrGate )
00662 eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 );
00663 else
00664 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
00665 Dec_GraphSetRoot( pGraph, eRoot );
00666 if ( pRoot->fPhase )
00667 Dec_GraphComplement( pGraph );
00668 return pGraph;
00669 }
00670
00682 Dec_Graph_t * Abc_ManResubQuit21( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, Abc_Obj_t * pObj2, int fOrGate )
00683 {
00684 Dec_Graph_t * pGraph;
00685 Dec_Edge_t eRoot, eNode0, eNode1, eNode2;
00686 assert( pObj0 != pObj1 );
00687 assert( !Abc_ObjIsComplement(pObj0) );
00688 assert( !Abc_ObjIsComplement(pObj1) );
00689 assert( !Abc_ObjIsComplement(pObj2) );
00690 pGraph = Dec_GraphCreate( 3 );
00691 Dec_GraphNode( pGraph, 0 )->pFunc = pObj0;
00692 Dec_GraphNode( pGraph, 1 )->pFunc = pObj1;
00693 Dec_GraphNode( pGraph, 2 )->pFunc = pObj2;
00694 eNode0 = Dec_EdgeCreate( 0, pObj0->fPhase );
00695 eNode1 = Dec_EdgeCreate( 1, pObj1->fPhase );
00696 eNode2 = Dec_EdgeCreate( 2, pObj2->fPhase );
00697 if ( fOrGate )
00698 {
00699 eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 );
00700 eRoot = Dec_GraphAddNodeOr( pGraph, eNode2, eRoot );
00701 }
00702 else
00703 {
00704 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
00705 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode2, eRoot );
00706 }
00707 Dec_GraphSetRoot( pGraph, eRoot );
00708 if ( pRoot->fPhase )
00709 Dec_GraphComplement( pGraph );
00710 return pGraph;
00711 }
00712
00724 Dec_Graph_t * Abc_ManResubQuit2( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, Abc_Obj_t * pObj2, int fOrGate )
00725 {
00726 Dec_Graph_t * pGraph;
00727 Dec_Edge_t eRoot, ePrev, eNode0, eNode1, eNode2;
00728 assert( pObj0 != pObj1 );
00729 assert( pObj0 != pObj2 );
00730 assert( pObj1 != pObj2 );
00731 assert( !Abc_ObjIsComplement(pObj0) );
00732 pGraph = Dec_GraphCreate( 3 );
00733 Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0);
00734 Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1);
00735 Dec_GraphNode( pGraph, 2 )->pFunc = Abc_ObjRegular(pObj2);
00736 eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase );
00737 if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) )
00738 {
00739 eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase );
00740 eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase );
00741 ePrev = Dec_GraphAddNodeOr( pGraph, eNode1, eNode2 );
00742 }
00743 else
00744 {
00745 eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) );
00746 eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) );
00747 ePrev = Dec_GraphAddNodeAnd( pGraph, eNode1, eNode2 );
00748 }
00749 if ( fOrGate )
00750 eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, ePrev );
00751 else
00752 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, ePrev );
00753 Dec_GraphSetRoot( pGraph, eRoot );
00754 if ( pRoot->fPhase )
00755 Dec_GraphComplement( pGraph );
00756 return pGraph;
00757 }
00758
00770 Dec_Graph_t * Abc_ManResubQuit3( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t * pObj1, Abc_Obj_t * pObj2, Abc_Obj_t * pObj3, int fOrGate )
00771 {
00772 Dec_Graph_t * pGraph;
00773 Dec_Edge_t eRoot, ePrev0, ePrev1, eNode0, eNode1, eNode2, eNode3;
00774 assert( pObj0 != pObj1 );
00775 assert( pObj2 != pObj3 );
00776 pGraph = Dec_GraphCreate( 4 );
00777 Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0);
00778 Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1);
00779 Dec_GraphNode( pGraph, 2 )->pFunc = Abc_ObjRegular(pObj2);
00780 Dec_GraphNode( pGraph, 3 )->pFunc = Abc_ObjRegular(pObj3);
00781 if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) )
00782 {
00783 eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase );
00784 eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase );
00785 ePrev0 = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 );
00786 if ( Abc_ObjIsComplement(pObj2) && Abc_ObjIsComplement(pObj3) )
00787 {
00788 eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase );
00789 eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase );
00790 ePrev1 = Dec_GraphAddNodeOr( pGraph, eNode2, eNode3 );
00791 }
00792 else
00793 {
00794 eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) );
00795 eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase ^ Abc_ObjIsComplement(pObj3) );
00796 ePrev1 = Dec_GraphAddNodeAnd( pGraph, eNode2, eNode3 );
00797 }
00798 }
00799 else
00800 {
00801 eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) );
00802 eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) );
00803 ePrev0 = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
00804 if ( Abc_ObjIsComplement(pObj2) && Abc_ObjIsComplement(pObj3) )
00805 {
00806 eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase );
00807 eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase );
00808 ePrev1 = Dec_GraphAddNodeOr( pGraph, eNode2, eNode3 );
00809 }
00810 else
00811 {
00812 eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) );
00813 eNode3 = Dec_EdgeCreate( 3, Abc_ObjRegular(pObj3)->fPhase ^ Abc_ObjIsComplement(pObj3) );
00814 ePrev1 = Dec_GraphAddNodeAnd( pGraph, eNode2, eNode3 );
00815 }
00816 }
00817 if ( fOrGate )
00818 eRoot = Dec_GraphAddNodeOr( pGraph, ePrev0, ePrev1 );
00819 else
00820 eRoot = Dec_GraphAddNodeAnd( pGraph, ePrev0, ePrev1 );
00821 Dec_GraphSetRoot( pGraph, eRoot );
00822 if ( pRoot->fPhase )
00823 Dec_GraphComplement( pGraph );
00824 return pGraph;
00825 }
00826
00827
00828
00829
00841 void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required )
00842 {
00843 Abc_Obj_t * pObj;
00844 unsigned * puData, * puDataR;
00845 int i, w;
00846 Vec_PtrClear( p->vDivs1UP );
00847 Vec_PtrClear( p->vDivs1UN );
00848 Vec_PtrClear( p->vDivs1B );
00849 puDataR = p->pRoot->pData;
00850 Vec_PtrForEachEntryStop( p->vDivs, pObj, i, p->nDivs )
00851 {
00852 if ( (int)pObj->Level > Required - 1 )
00853 continue;
00854
00855 puData = pObj->pData;
00856
00857 for ( w = 0; w < p->nWords; w++ )
00858
00859 if ( puData[w] & ~puDataR[w] & p->pCareSet[w] )
00860 break;
00861 if ( w == p->nWords )
00862 {
00863 Vec_PtrPush( p->vDivs1UP, pObj );
00864 continue;
00865 }
00866
00867 for ( w = 0; w < p->nWords; w++ )
00868
00869 if ( ~puData[w] & puDataR[w] & p->pCareSet[w] )
00870 break;
00871 if ( w == p->nWords )
00872 {
00873 Vec_PtrPush( p->vDivs1UN, pObj );
00874 continue;
00875 }
00876
00877 Vec_PtrPush( p->vDivs1B, pObj );
00878 }
00879 }
00880
00892 void Abc_ManResubDivsD( Abc_ManRes_t * p, int Required )
00893 {
00894 Abc_Obj_t * pObj0, * pObj1;
00895 unsigned * puData0, * puData1, * puDataR;
00896 int i, k, w;
00897 Vec_PtrClear( p->vDivs2UP0 );
00898 Vec_PtrClear( p->vDivs2UP1 );
00899 Vec_PtrClear( p->vDivs2UN0 );
00900 Vec_PtrClear( p->vDivs2UN1 );
00901 puDataR = p->pRoot->pData;
00902 Vec_PtrForEachEntry( p->vDivs1B, pObj0, i )
00903 {
00904 if ( (int)pObj0->Level > Required - 2 )
00905 continue;
00906
00907 puData0 = pObj0->pData;
00908 Vec_PtrForEachEntryStart( p->vDivs1B, pObj1, k, i + 1 )
00909 {
00910 if ( (int)pObj1->Level > Required - 2 )
00911 continue;
00912
00913 puData1 = pObj1->pData;
00914
00915 if ( Vec_PtrSize(p->vDivs2UP0) < ABC_RS_DIV2_MAX )
00916 {
00917
00918 for ( w = 0; w < p->nWords; w++ )
00919
00920 if ( (puData0[w] & puData1[w]) & ~puDataR[w] & p->pCareSet[w] )
00921 break;
00922 if ( w == p->nWords )
00923 {
00924 Vec_PtrPush( p->vDivs2UP0, pObj0 );
00925 Vec_PtrPush( p->vDivs2UP1, pObj1 );
00926 }
00927 for ( w = 0; w < p->nWords; w++ )
00928
00929 if ( (~puData0[w] & puData1[w]) & ~puDataR[w] & p->pCareSet[w] )
00930 break;
00931 if ( w == p->nWords )
00932 {
00933 Vec_PtrPush( p->vDivs2UP0, Abc_ObjNot(pObj0) );
00934 Vec_PtrPush( p->vDivs2UP1, pObj1 );
00935 }
00936 for ( w = 0; w < p->nWords; w++ )
00937
00938 if ( (puData0[w] & ~puData1[w]) & ~puDataR[w] & p->pCareSet[w] )
00939 break;
00940 if ( w == p->nWords )
00941 {
00942 Vec_PtrPush( p->vDivs2UP0, pObj0 );
00943 Vec_PtrPush( p->vDivs2UP1, Abc_ObjNot(pObj1) );
00944 }
00945 for ( w = 0; w < p->nWords; w++ )
00946
00947 if ( (puData0[w] | puData1[w]) & ~puDataR[w] & p->pCareSet[w] )
00948 break;
00949 if ( w == p->nWords )
00950 {
00951 Vec_PtrPush( p->vDivs2UP0, Abc_ObjNot(pObj0) );
00952 Vec_PtrPush( p->vDivs2UP1, Abc_ObjNot(pObj1) );
00953 }
00954 }
00955
00956 if ( Vec_PtrSize(p->vDivs2UN0) < ABC_RS_DIV2_MAX )
00957 {
00958
00959 for ( w = 0; w < p->nWords; w++ )
00960
00961 if ( ~(puData0[w] & puData1[w]) & puDataR[w] & p->pCareSet[w] )
00962 break;
00963 if ( w == p->nWords )
00964 {
00965 Vec_PtrPush( p->vDivs2UN0, pObj0 );
00966 Vec_PtrPush( p->vDivs2UN1, pObj1 );
00967 }
00968 for ( w = 0; w < p->nWords; w++ )
00969
00970 if ( ~(~puData0[w] & puData1[w]) & puDataR[w] & p->pCareSet[w] )
00971 break;
00972 if ( w == p->nWords )
00973 {
00974 Vec_PtrPush( p->vDivs2UN0, Abc_ObjNot(pObj0) );
00975 Vec_PtrPush( p->vDivs2UN1, pObj1 );
00976 }
00977 for ( w = 0; w < p->nWords; w++ )
00978
00979 if ( ~(puData0[w] & ~puData1[w]) & puDataR[w] & p->pCareSet[w] )
00980 break;
00981 if ( w == p->nWords )
00982 {
00983 Vec_PtrPush( p->vDivs2UN0, pObj0 );
00984 Vec_PtrPush( p->vDivs2UN1, Abc_ObjNot(pObj1) );
00985 }
00986 for ( w = 0; w < p->nWords; w++ )
00987
00988 if ( ~(puData0[w] | puData1[w]) & puDataR[w] & p->pCareSet[w] )
00989 break;
00990 if ( w == p->nWords )
00991 {
00992 Vec_PtrPush( p->vDivs2UN0, Abc_ObjNot(pObj0) );
00993 Vec_PtrPush( p->vDivs2UN1, Abc_ObjNot(pObj1) );
00994 }
00995 }
00996 }
00997 }
00998
00999 }
01000
01001
01002
01014 Dec_Graph_t * Abc_ManResubQuit( Abc_ManRes_t * p )
01015 {
01016 Dec_Graph_t * pGraph;
01017 unsigned * upData;
01018 int w;
01019 upData = p->pRoot->pData;
01020 for ( w = 0; w < p->nWords; w++ )
01021
01022 if ( upData[w] & p->pCareSet[w] )
01023 break;
01024 if ( w != p->nWords )
01025 return NULL;
01026
01027 if ( p->pRoot->fPhase )
01028 pGraph = Dec_GraphCreateConst1();
01029 else
01030 pGraph = Dec_GraphCreateConst0();
01031 return pGraph;
01032 }
01033
01045 Dec_Graph_t * Abc_ManResubDivs0( Abc_ManRes_t * p )
01046 {
01047 Abc_Obj_t * pObj;
01048 unsigned * puData, * puDataR;
01049 int i, w;
01050 puDataR = p->pRoot->pData;
01051 Vec_PtrForEachEntryStop( p->vDivs, pObj, i, p->nDivs )
01052 {
01053 puData = pObj->pData;
01054 for ( w = 0; w < p->nWords; w++ )
01055
01056 if ( (puData[w] ^ puDataR[w]) & p->pCareSet[w] )
01057 break;
01058 if ( w == p->nWords )
01059 return Abc_ManResubQuit0( p->pRoot, pObj );
01060 }
01061 return NULL;
01062 }
01063
01075 Dec_Graph_t * Abc_ManResubDivs1( Abc_ManRes_t * p, int Required )
01076 {
01077 Abc_Obj_t * pObj0, * pObj1;
01078 unsigned * puData0, * puData1, * puDataR;
01079 int i, k, w;
01080 puDataR = p->pRoot->pData;
01081
01082 Vec_PtrForEachEntry( p->vDivs1UP, pObj0, i )
01083 {
01084 puData0 = pObj0->pData;
01085 Vec_PtrForEachEntryStart( p->vDivs1UP, pObj1, k, i + 1 )
01086 {
01087 puData1 = pObj1->pData;
01088 for ( w = 0; w < p->nWords; w++ )
01089
01090 if ( ((puData0[w] | puData1[w]) ^ puDataR[w]) & p->pCareSet[w] )
01091 break;
01092 if ( w == p->nWords )
01093 {
01094 p->nUsedNode1Or++;
01095 return Abc_ManResubQuit1( p->pRoot, pObj0, pObj1, 1 );
01096 }
01097 }
01098 }
01099
01100 Vec_PtrForEachEntry( p->vDivs1UN, pObj0, i )
01101 {
01102 puData0 = pObj0->pData;
01103 Vec_PtrForEachEntryStart( p->vDivs1UN, pObj1, k, i + 1 )
01104 {
01105 puData1 = pObj1->pData;
01106 for ( w = 0; w < p->nWords; w++ )
01107
01108 if ( ((puData0[w] & puData1[w]) ^ puDataR[w]) & p->pCareSet[w] )
01109 break;
01110 if ( w == p->nWords )
01111 {
01112 p->nUsedNode1And++;
01113 return Abc_ManResubQuit1( p->pRoot, pObj0, pObj1, 0 );
01114 }
01115 }
01116 }
01117 return NULL;
01118 }
01119
01131 Dec_Graph_t * Abc_ManResubDivs12( Abc_ManRes_t * p, int Required )
01132 {
01133 Abc_Obj_t * pObj0, * pObj1, * pObj2, * pObjMax, * pObjMin0, * pObjMin1;
01134 unsigned * puData0, * puData1, * puData2, * puDataR;
01135 int i, k, j, w, LevelMax;
01136 puDataR = p->pRoot->pData;
01137
01138 Vec_PtrForEachEntry( p->vDivs1UP, pObj0, i )
01139 {
01140 puData0 = pObj0->pData;
01141 Vec_PtrForEachEntryStart( p->vDivs1UP, pObj1, k, i + 1 )
01142 {
01143 puData1 = pObj1->pData;
01144 Vec_PtrForEachEntryStart( p->vDivs1UP, pObj2, j, k + 1 )
01145 {
01146 puData2 = pObj2->pData;
01147 for ( w = 0; w < p->nWords; w++ )
01148
01149 if ( ((puData0[w] | puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] )
01150 break;
01151 if ( w == p->nWords )
01152 {
01153 LevelMax = ABC_MAX( pObj0->Level, ABC_MAX(pObj1->Level, pObj2->Level) );
01154 assert( LevelMax <= Required - 1 );
01155
01156 pObjMax = NULL;
01157 if ( (int)pObj0->Level == LevelMax )
01158 pObjMax = pObj0, pObjMin0 = pObj1, pObjMin1 = pObj2;
01159 if ( (int)pObj1->Level == LevelMax )
01160 {
01161 if ( pObjMax ) continue;
01162 pObjMax = pObj1, pObjMin0 = pObj0, pObjMin1 = pObj2;
01163 }
01164 if ( (int)pObj2->Level == LevelMax )
01165 {
01166 if ( pObjMax ) continue;
01167 pObjMax = pObj2, pObjMin0 = pObj0, pObjMin1 = pObj1;
01168 }
01169
01170 p->nUsedNode2Or++;
01171 return Abc_ManResubQuit21( p->pRoot, pObjMin0, pObjMin1, pObjMax, 1 );
01172 }
01173 }
01174 }
01175 }
01176
01177 Vec_PtrForEachEntry( p->vDivs1UN, pObj0, i )
01178 {
01179 puData0 = pObj0->pData;
01180 Vec_PtrForEachEntryStart( p->vDivs1UN, pObj1, k, i + 1 )
01181 {
01182 puData1 = pObj1->pData;
01183 Vec_PtrForEachEntryStart( p->vDivs1UN, pObj2, j, k + 1 )
01184 {
01185 puData2 = pObj2->pData;
01186 for ( w = 0; w < p->nWords; w++ )
01187
01188 if ( ((puData0[w] & puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] )
01189 break;
01190 if ( w == p->nWords )
01191 {
01192 LevelMax = ABC_MAX( pObj0->Level, ABC_MAX(pObj1->Level, pObj2->Level) );
01193 assert( LevelMax <= Required - 1 );
01194
01195 pObjMax = NULL;
01196 if ( (int)pObj0->Level == LevelMax )
01197 pObjMax = pObj0, pObjMin0 = pObj1, pObjMin1 = pObj2;
01198 if ( (int)pObj1->Level == LevelMax )
01199 {
01200 if ( pObjMax ) continue;
01201 pObjMax = pObj1, pObjMin0 = pObj0, pObjMin1 = pObj2;
01202 }
01203 if ( (int)pObj2->Level == LevelMax )
01204 {
01205 if ( pObjMax ) continue;
01206 pObjMax = pObj2, pObjMin0 = pObj0, pObjMin1 = pObj1;
01207 }
01208
01209 p->nUsedNode2And++;
01210 return Abc_ManResubQuit21( p->pRoot, pObjMin0, pObjMin1, pObjMax, 0 );
01211 }
01212 }
01213 }
01214 }
01215 return NULL;
01216 }
01217
01229 Dec_Graph_t * Abc_ManResubDivs2( Abc_ManRes_t * p, int Required )
01230 {
01231 Abc_Obj_t * pObj0, * pObj1, * pObj2;
01232 unsigned * puData0, * puData1, * puData2, * puDataR;
01233 int i, k, w;
01234 puDataR = p->pRoot->pData;
01235
01236 Vec_PtrForEachEntry( p->vDivs1UP, pObj0, i )
01237 {
01238 puData0 = pObj0->pData;
01239 Vec_PtrForEachEntry( p->vDivs2UP0, pObj1, k )
01240 {
01241 pObj2 = Vec_PtrEntry( p->vDivs2UP1, k );
01242
01243 puData1 = Abc_ObjRegular(pObj1)->pData;
01244 puData2 = Abc_ObjRegular(pObj2)->pData;
01245 if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) )
01246 {
01247 for ( w = 0; w < p->nWords; w++ )
01248
01249 if ( ((puData0[w] | (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01250 break;
01251 }
01252 else if ( Abc_ObjIsComplement(pObj1) )
01253 {
01254 for ( w = 0; w < p->nWords; w++ )
01255
01256 if ( ((puData0[w] | (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01257 break;
01258 }
01259 else if ( Abc_ObjIsComplement(pObj2) )
01260 {
01261 for ( w = 0; w < p->nWords; w++ )
01262
01263 if ( ((puData0[w] | (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01264 break;
01265 }
01266 else
01267 {
01268 for ( w = 0; w < p->nWords; w++ )
01269
01270 if ( ((puData0[w] | (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01271 break;
01272 }
01273 if ( w == p->nWords )
01274 {
01275 p->nUsedNode2OrAnd++;
01276 return Abc_ManResubQuit2( p->pRoot, pObj0, pObj1, pObj2, 1 );
01277 }
01278 }
01279 }
01280
01281 Vec_PtrForEachEntry( p->vDivs1UN, pObj0, i )
01282 {
01283 puData0 = pObj0->pData;
01284 Vec_PtrForEachEntry( p->vDivs2UN0, pObj1, k )
01285 {
01286 pObj2 = Vec_PtrEntry( p->vDivs2UN1, k );
01287
01288 puData1 = Abc_ObjRegular(pObj1)->pData;
01289 puData2 = Abc_ObjRegular(pObj2)->pData;
01290 if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) )
01291 {
01292 for ( w = 0; w < p->nWords; w++ )
01293
01294 if ( ((puData0[w] & (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01295 break;
01296 }
01297 else if ( Abc_ObjIsComplement(pObj1) )
01298 {
01299 for ( w = 0; w < p->nWords; w++ )
01300
01301 if ( ((puData0[w] & (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01302 break;
01303 }
01304 else if ( Abc_ObjIsComplement(pObj2) )
01305 {
01306 for ( w = 0; w < p->nWords; w++ )
01307
01308 if ( ((puData0[w] & (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01309 break;
01310 }
01311 else
01312 {
01313 for ( w = 0; w < p->nWords; w++ )
01314
01315 if ( ((puData0[w] & (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] )
01316 break;
01317 }
01318 if ( w == p->nWords )
01319 {
01320 p->nUsedNode2AndOr++;
01321 return Abc_ManResubQuit2( p->pRoot, pObj0, pObj1, pObj2, 0 );
01322 }
01323 }
01324 }
01325 return NULL;
01326 }
01327
01339 Dec_Graph_t * Abc_ManResubDivs3( Abc_ManRes_t * p, int Required )
01340 {
01341 Abc_Obj_t * pObj0, * pObj1, * pObj2, * pObj3;
01342 unsigned * puData0, * puData1, * puData2, * puData3, * puDataR;
01343 int i, k, w, Flag;
01344 puDataR = p->pRoot->pData;
01345
01346 Vec_PtrForEachEntry( p->vDivs2UP0, pObj0, i )
01347 {
01348 pObj1 = Vec_PtrEntry( p->vDivs2UP1, i );
01349 puData0 = Abc_ObjRegular(pObj0)->pData;
01350 puData1 = Abc_ObjRegular(pObj1)->pData;
01351 Flag = (Abc_ObjIsComplement(pObj0) << 3) | (Abc_ObjIsComplement(pObj1) << 2);
01352
01353 Vec_PtrForEachEntryStart( p->vDivs2UP0, pObj2, k, i + 1 )
01354 {
01355 pObj3 = Vec_PtrEntry( p->vDivs2UP1, k );
01356 puData2 = Abc_ObjRegular(pObj2)->pData;
01357 puData3 = Abc_ObjRegular(pObj3)->pData;
01358
01359 Flag = (Flag & 12) | (Abc_ObjIsComplement(pObj2) << 1) | Abc_ObjIsComplement(pObj3);
01360 assert( Flag < 16 );
01361 switch( Flag )
01362 {
01363 case 0:
01364 for ( w = 0; w < p->nWords; w++ )
01365
01366 if ( (((puData0[w] & puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01367 break;
01368 break;
01369 case 1:
01370 for ( w = 0; w < p->nWords; w++ )
01371
01372 if ( (((puData0[w] & puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01373 break;
01374 break;
01375 case 2:
01376 for ( w = 0; w < p->nWords; w++ )
01377
01378 if ( (((puData0[w] & puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01379 break;
01380 break;
01381 case 3:
01382 for ( w = 0; w < p->nWords; w++ )
01383
01384 if ( (((puData0[w] & puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01385 break;
01386 break;
01387
01388 case 4:
01389 for ( w = 0; w < p->nWords; w++ )
01390
01391 if ( (((puData0[w] & ~puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01392 break;
01393 break;
01394 case 5:
01395 for ( w = 0; w < p->nWords; w++ )
01396
01397 if ( (((puData0[w] & ~puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01398 break;
01399 break;
01400 case 6:
01401 for ( w = 0; w < p->nWords; w++ )
01402
01403 if ( (((puData0[w] & ~puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01404 break;
01405 break;
01406 case 7:
01407 for ( w = 0; w < p->nWords; w++ )
01408
01409 if ( (((puData0[w] & ~puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01410 break;
01411 break;
01412
01413 case 8:
01414 for ( w = 0; w < p->nWords; w++ )
01415
01416 if ( (((~puData0[w] & puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01417 break;
01418 break;
01419 case 9:
01420 for ( w = 0; w < p->nWords; w++ )
01421
01422 if ( (((~puData0[w] & puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01423 break;
01424 break;
01425 case 10:
01426 for ( w = 0; w < p->nWords; w++ )
01427
01428 if ( (((~puData0[w] & puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01429 break;
01430 break;
01431 case 11:
01432 for ( w = 0; w < p->nWords; w++ )
01433
01434 if ( (((~puData0[w] & puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01435 break;
01436 break;
01437
01438 case 12:
01439 for ( w = 0; w < p->nWords; w++ )
01440
01441 if ( (((puData0[w] | puData1[w]) | (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01442 break;
01443 break;
01444 case 13:
01445 for ( w = 0; w < p->nWords; w++ )
01446
01447 if ( (((puData0[w] | puData1[w]) | (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01448 break;
01449 break;
01450 case 14:
01451 for ( w = 0; w < p->nWords; w++ )
01452
01453 if ( (((puData0[w] | puData1[w]) | (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01454 break;
01455 break;
01456 case 15:
01457 for ( w = 0; w < p->nWords; w++ )
01458
01459 if ( (((puData0[w] | puData1[w]) | (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] )
01460 break;
01461 break;
01462
01463 }
01464 if ( w == p->nWords )
01465 {
01466 p->nUsedNode3OrAnd++;
01467 return Abc_ManResubQuit3( p->pRoot, pObj0, pObj1, pObj2, pObj3, 1 );
01468 }
01469 }
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583 return NULL;
01584 }
01585
01597 void Abc_ManResubCleanup( Abc_ManRes_t * p )
01598 {
01599 Abc_Obj_t * pObj;
01600 int i;
01601 Vec_PtrForEachEntry( p->vDivs, pObj, i )
01602 pObj->pData = NULL;
01603 Vec_PtrClear( p->vDivs );
01604 p->pRoot = NULL;
01605 }
01606
01618 Dec_Graph_t * Abc_ManResubEval( Abc_ManRes_t * p, Abc_Obj_t * pRoot, Vec_Ptr_t * vLeaves, int nSteps, bool fUpdateLevel, bool fVerbose )
01619 {
01620 extern int Abc_NodeMffsInside( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vInside );
01621 Dec_Graph_t * pGraph;
01622 int Required;
01623 int clk;
01624
01625 Required = fUpdateLevel? Abc_ObjRequiredLevel(pRoot) : ABC_INFINITY;
01626
01627 assert( nSteps >= 0 );
01628 assert( nSteps <= 3 );
01629 p->pRoot = pRoot;
01630 p->nLeaves = Vec_PtrSize(vLeaves);
01631 p->nLastGain = -1;
01632
01633
01634 clk = clock();
01635 p->nMffc = Abc_NodeMffsInside( pRoot, vLeaves, p->vTemp );
01636 p->timeMffc += clock() - clk;
01637 assert( p->nMffc > 0 );
01638
01639
01640 clk = clock();
01641 if ( !Abc_ManResubCollectDivs( p, pRoot, vLeaves, Required ) )
01642 return NULL;
01643 p->timeDiv += clock() - clk;
01644
01645 p->nTotalDivs += p->nDivs;
01646 p->nTotalLeaves += p->nLeaves;
01647
01648
01649 clk = clock();
01650 Abc_ManResubSimulate( p->vDivs, p->nLeaves, p->vSims, p->nLeavesMax, p->nWords );
01651 p->timeSim += clock() - clk;
01652
01653 clk = clock();
01654
01655 if ( pGraph = Abc_ManResubQuit( p ) )
01656 {
01657 p->nUsedNodeC++;
01658 p->nLastGain = p->nMffc;
01659 return pGraph;
01660 }
01661
01662
01663 if ( pGraph = Abc_ManResubDivs0( p ) )
01664 {
01665 p->timeRes1 += clock() - clk;
01666 p->nUsedNode0++;
01667 p->nLastGain = p->nMffc;
01668 return pGraph;
01669 }
01670 if ( nSteps == 0 || p->nMffc == 1 )
01671 {
01672 p->timeRes1 += clock() - clk;
01673 return NULL;
01674 }
01675
01676
01677 Abc_ManResubDivsS( p, Required );
01678
01679
01680 if ( pGraph = Abc_ManResubDivs1( p, Required ) )
01681 {
01682 p->timeRes1 += clock() - clk;
01683 p->nLastGain = p->nMffc - 1;
01684 return pGraph;
01685 }
01686 p->timeRes1 += clock() - clk;
01687 if ( nSteps == 1 || p->nMffc == 2 )
01688 return NULL;
01689
01690 clk = clock();
01691
01692 if ( pGraph = Abc_ManResubDivs12( p, Required ) )
01693 {
01694 p->timeRes2 += clock() - clk;
01695 p->nLastGain = p->nMffc - 2;
01696 return pGraph;
01697 }
01698 p->timeRes2 += clock() - clk;
01699
01700
01701 clk = clock();
01702 Abc_ManResubDivsD( p, Required );
01703 p->timeResD += clock() - clk;
01704
01705
01706 clk = clock();
01707 if ( pGraph = Abc_ManResubDivs2( p, Required ) )
01708 {
01709 p->timeRes2 += clock() - clk;
01710 p->nLastGain = p->nMffc - 2;
01711 return pGraph;
01712 }
01713 p->timeRes2 += clock() - clk;
01714 if ( nSteps == 2 || p->nMffc == 3 )
01715 return NULL;
01716
01717
01718 clk = clock();
01719 if ( pGraph = Abc_ManResubDivs3( p, Required ) )
01720 {
01721 p->timeRes3 += clock() - clk;
01722 p->nLastGain = p->nMffc - 3;
01723 return pGraph;
01724 }
01725 p->timeRes3 += clock() - clk;
01726 if ( nSteps == 3 || p->nLeavesMax == 4 )
01727 return NULL;
01728 return NULL;
01729 }
01730
01731
01732
01733
01745 int Abc_CutVolumeCheck_rec( Abc_Obj_t * pObj )
01746 {
01747
01748 if ( Abc_NodeIsTravIdCurrent(pObj) )
01749 return 0;
01750 Abc_NodeSetTravIdCurrent(pObj);
01751
01752 if ( Abc_ObjIsCi(pObj) )
01753 printf( "Abc_CutVolumeCheck() ERROR: The set of nodes is not a cut!\n" );
01754
01755 return 1 + Abc_CutVolumeCheck_rec( Abc_ObjFanin0(pObj) ) +
01756 Abc_CutVolumeCheck_rec( Abc_ObjFanin1(pObj) );
01757 }
01758
01770 int Abc_CutVolumeCheck( Abc_Obj_t * pNode, Vec_Ptr_t * vLeaves )
01771 {
01772 Abc_Obj_t * pObj;
01773 int i;
01774
01775 Abc_NtkIncrementTravId( pNode->pNtk );
01776 Vec_PtrForEachEntry( vLeaves, pObj, i )
01777 Abc_NodeSetTravIdCurrent( pObj );
01778
01779 return Abc_CutVolumeCheck_rec( pNode );
01780 }
01781
01793 void Abc_CutFactor_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
01794 {
01795 if ( pObj->fMarkA )
01796 return;
01797 if ( Abc_ObjIsCi(pObj) || (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)) )
01798 {
01799 Vec_PtrPush( vLeaves, pObj );
01800 pObj->fMarkA = 1;
01801 return;
01802 }
01803 Abc_CutFactor_rec( Abc_ObjFanin0(pObj), vLeaves );
01804 Abc_CutFactor_rec( Abc_ObjFanin1(pObj), vLeaves );
01805 }
01806
01820 Vec_Ptr_t * Abc_CutFactor( Abc_Obj_t * pNode )
01821 {
01822 Vec_Ptr_t * vLeaves;
01823 Abc_Obj_t * pObj;
01824 int i;
01825 assert( !Abc_ObjIsCi(pNode) );
01826 vLeaves = Vec_PtrAlloc( 10 );
01827 Abc_CutFactor_rec( Abc_ObjFanin0(pNode), vLeaves );
01828 Abc_CutFactor_rec( Abc_ObjFanin1(pNode), vLeaves );
01829 Vec_PtrForEachEntry( vLeaves, pObj, i )
01830 pObj->fMarkA = 0;
01831 return vLeaves;
01832 }
01833
01850 Vec_Ptr_t * Abc_CutFactorLarge( Abc_Obj_t * pNode, int nLeavesMax )
01851 {
01852 Vec_Ptr_t * vLeaves, * vFactors, * vFact, * vNext;
01853 Vec_Int_t * vFeasible;
01854 Abc_Obj_t * pLeaf, * pTemp;
01855 int i, k, Counter, RandLeaf;
01856 int BestCut, BestShare;
01857 assert( Abc_ObjIsNode(pNode) );
01858
01859 vLeaves = Abc_CutFactor( pNode );
01860 if ( Vec_PtrSize(vLeaves) > nLeavesMax )
01861 {
01862 Vec_PtrFree(vLeaves);
01863 return NULL;
01864 }
01865 if ( Vec_PtrSize(vLeaves) == nLeavesMax )
01866 return vLeaves;
01867
01868 vFactors = Vec_PtrAlloc( nLeavesMax );
01869 Abc_NtkIncrementTravId( pNode->pNtk );
01870 Vec_PtrForEachEntry( vLeaves, pLeaf, i )
01871 {
01872 Abc_NodeSetTravIdCurrent( pLeaf );
01873 if ( Abc_ObjIsCi(pLeaf) )
01874 Vec_PtrPush( vFactors, NULL );
01875 else
01876 Vec_PtrPush( vFactors, Abc_CutFactor(pLeaf) );
01877 }
01878
01879 vFeasible = Vec_IntAlloc( nLeavesMax );
01880 while ( 1 )
01881 {
01882 BestCut = -1;
01883
01884 Vec_IntClear( vFeasible );
01885 Vec_PtrForEachEntry( vFactors, vFact, i )
01886 {
01887 if ( vFact == NULL )
01888 continue;
01889
01890 Counter = 0;
01891 Vec_PtrForEachEntry( vFact, pTemp, k )
01892 Counter += !Abc_NodeIsTravIdCurrent(pTemp);
01893
01894 if ( Counter <= nLeavesMax - Vec_PtrSize(vLeaves) + 1 )
01895 {
01896 Vec_IntPush( vFeasible, i );
01897 if ( BestCut == -1 || BestShare < Vec_PtrSize(vFact) - Counter )
01898 BestCut = i, BestShare = Vec_PtrSize(vFact) - Counter;
01899 }
01900 }
01901
01902 if ( Vec_IntSize(vFeasible) == 0 )
01903 break;
01904
01905
01906
01907 RandLeaf = BestCut;
01908
01909 pLeaf = Vec_PtrEntry( vLeaves, RandLeaf );
01910 vNext = Vec_PtrEntry( vFactors, RandLeaf );
01911
01912 Abc_NodeSetTravIdPrevious( pLeaf );
01913
01914 for ( i = RandLeaf; i < Vec_PtrSize(vLeaves)-1; i++ )
01915 {
01916 Vec_PtrWriteEntry( vLeaves, i, Vec_PtrEntry(vLeaves, i+1) );
01917 Vec_PtrWriteEntry( vFactors, i, Vec_PtrEntry(vFactors,i+1) );
01918 }
01919 Vec_PtrShrink( vLeaves, Vec_PtrSize(vLeaves) -1 );
01920 Vec_PtrShrink( vFactors, Vec_PtrSize(vFactors)-1 );
01921
01922 Vec_PtrForEachEntry( vNext, pLeaf, i )
01923 {
01924 if ( Abc_NodeIsTravIdCurrent(pLeaf) )
01925 continue;
01926 Abc_NodeSetTravIdCurrent( pLeaf );
01927 Vec_PtrPush( vLeaves, pLeaf );
01928 if ( Abc_ObjIsCi(pLeaf) )
01929 Vec_PtrPush( vFactors, NULL );
01930 else
01931 Vec_PtrPush( vFactors, Abc_CutFactor(pLeaf) );
01932 }
01933 Vec_PtrFree( vNext );
01934 assert( Vec_PtrSize(vLeaves) <= nLeavesMax );
01935 if ( Vec_PtrSize(vLeaves) == nLeavesMax )
01936 break;
01937 }
01938
01939
01940 Vec_PtrForEachEntry( vFactors, vFact, i )
01941 if ( vFact ) Vec_PtrFree( vFact );
01942 Vec_PtrFree( vFactors );
01943 Vec_IntFree( vFeasible );
01944 return vLeaves;
01945 }
01946
01950
01951