00001
00021 #include "lpkInt.h"
00022
00026
00030
00042 void Lpk_CreateVarOrder( Kit_DsdNtk_t * pNtk, char pTable[][16] )
00043 {
00044 Kit_DsdObj_t * pObj;
00045 unsigned uSuppFanins, k;
00046 int Above[16], Below[16];
00047 int nAbove, nBelow, iFaninLit, i, x, y;
00048
00049 Kit_DsdNtkForEachObj( pNtk, pObj, i )
00050 {
00051
00052 nAbove = 0;
00053 uSuppFanins = 0;
00054 Kit_DsdObjForEachFanin( pNtk, pObj, iFaninLit, k )
00055 {
00056 if ( Kit_DsdLitIsLeaf( pNtk, iFaninLit ) )
00057 Above[nAbove++] = Kit_DsdLit2Var(iFaninLit);
00058 else
00059 uSuppFanins |= Kit_DsdLitSupport( pNtk, iFaninLit );
00060 }
00061
00062 nBelow = 0;
00063 for ( y = 0; y < 16; y++ )
00064 if ( uSuppFanins & (1 << y) )
00065 Below[nBelow++] = y;
00066
00067 for ( x = 0; x < nAbove; x++ )
00068 for ( y = 0; y < nBelow; y++ )
00069 pTable[Above[x]][Below[y]]++;
00070 }
00071 }
00072
00084 void Lpk_CreateCommonOrder( char pTable[][16], int piCofVar[], int nCBars, int pPrios[], int nVars, int fVerbose )
00085 {
00086 int Score[16] = {0}, pPres[16];
00087 int i, y, x, iVarBest, ScoreMax, PrioCount;
00088
00089
00090 for ( i = 0; i < nVars; i++ )
00091 pPres[i] = 1;
00092
00093 for ( i = 0; i < nCBars; i++ )
00094 pPres[piCofVar[i]] = 0;
00095
00096
00097 for ( i = 0; i < nVars; i++ )
00098 {
00099 if ( pPres[i] == 0 )
00100 continue;
00101 for ( y = 0; y < nVars; y++ )
00102 Score[i] += pTable[i][y];
00103 for ( x = 0; x < nVars; x++ )
00104 Score[i] -= pTable[x][i];
00105 }
00106
00107
00108 if ( fVerbose )
00109 {
00110 printf( "Scores: " );
00111 for ( i = 0; i < nVars; i++ )
00112 printf( "%c=%d ", 'a'+i, Score[i] );
00113 printf( " " );
00114 printf( "Prios: " );
00115 }
00116
00117
00118
00119 for ( i = 0; i < nVars; i++ )
00120 pPrios[i] = 16;
00121
00122
00123 for ( PrioCount = 1; ; PrioCount++ )
00124 {
00125
00126 iVarBest = -1;
00127 ScoreMax = -100000;
00128 for ( i = 0; i < nVars; i++ )
00129 {
00130 if ( pPres[i] == 0 )
00131 continue;
00132 if ( ScoreMax < Score[i] )
00133 {
00134 ScoreMax = Score[i];
00135 iVarBest = i;
00136 }
00137 }
00138 if ( iVarBest == -1 )
00139 break;
00140
00141 if ( fVerbose )
00142 printf( "%d=", PrioCount );
00143 for ( i = 0; i < nVars; i++ )
00144 {
00145 if ( pPres[i] == 0 )
00146 continue;
00147 if ( Score[i] == ScoreMax )
00148 {
00149 pPrios[i] = PrioCount;
00150 pPres[i] = 0;
00151 if ( fVerbose )
00152 printf( "%c", 'a'+i );
00153 }
00154 }
00155 if ( fVerbose )
00156 printf( " " );
00157 }
00158 if ( fVerbose )
00159 printf( "\n" );
00160 }
00161
00173 int Lpk_FindHighest( Kit_DsdNtk_t ** ppNtks, int * piLits, int nSize, int * pPrio, int * pDecision )
00174 {
00175 Kit_DsdObj_t * pObj;
00176 unsigned uSupps[8], uSuppFanin, uSuppTotal, uSuppLarge;
00177 int i, pTriv[8], PrioMin, iVarMax, nComps, fOneNonTriv;
00178
00179
00180 uSuppTotal = 0;
00181 for ( i = 0; i < nSize; i++ )
00182 {
00183 pTriv[i] = 1;
00184 if ( piLits[i] < 0 )
00185 uSupps[i] = 0;
00186 else if ( Kit_DsdLitIsLeaf(ppNtks[i], piLits[i]) )
00187 uSupps[i] = Kit_DsdLitSupport( ppNtks[i], piLits[i] );
00188 else
00189 {
00190 pObj = Kit_DsdNtkObj( ppNtks[i], Kit_DsdLit2Var(piLits[i]) );
00191 if ( pObj->Type == KIT_DSD_PRIME )
00192 {
00193 pTriv[i] = 0;
00194 uSuppFanin = Kit_DsdLitSupport( ppNtks[i], pObj->pFans[0] );
00195 }
00196 else
00197 {
00198 assert( pObj->nFans == 2 );
00199 if ( !Kit_DsdLitIsLeaf(ppNtks[i], pObj->pFans[0]) )
00200 pTriv[i] = 0;
00201 uSuppFanin = Kit_DsdLitSupport( ppNtks[i], pObj->pFans[1] );
00202 }
00203 uSupps[i] = Kit_DsdLitSupport( ppNtks[i], piLits[i] ) & ~uSuppFanin;
00204 }
00205 assert( uSupps[i] <= 0xFFFF );
00206 uSuppTotal |= uSupps[i];
00207 }
00208 if ( uSuppTotal == 0 )
00209 return 0;
00210
00211
00212 PrioMin = ABC_INFINITY;
00213 iVarMax = -1;
00214 for ( i = 0; i < 16; i++ )
00215 if ( uSuppTotal & (1 << i) )
00216 if ( PrioMin > pPrio[i] )
00217 {
00218 PrioMin = pPrio[i];
00219 iVarMax = i;
00220 }
00221 assert( iVarMax != -1 );
00222
00223
00224 nComps = 0;
00225 fOneNonTriv = 0;
00226 uSuppLarge = 0;
00227 for ( i = 0; i < nSize; i++ )
00228 if ( uSupps[i] & (1<<iVarMax) )
00229 {
00230 if ( pTriv[i] || !fOneNonTriv )
00231 {
00232 if ( !pTriv[i] )
00233 {
00234 uSuppLarge = uSupps[i];
00235 fOneNonTriv = 1;
00236 }
00237 pDecision[i] = 1;
00238 nComps++;
00239 }
00240 else
00241 pDecision[i] = 0;
00242 }
00243 else
00244 pDecision[i] = 0;
00245
00246
00247 if ( fOneNonTriv )
00248 for ( i = 0; i < nSize; i++ )
00249 if ( !pTriv[i] && pDecision[i] == 0 && (uSupps[i] & ~uSuppLarge) == 0 )
00250 {
00251 pDecision[i] = 1;
00252 nComps++;
00253 }
00254
00255 return nComps;
00256 }
00257
00269 If_Obj_t * Lpk_MapTreeMulti_rec( Lpk_Man_t * p, Kit_DsdNtk_t ** ppNtks, int * piLits, int * piCofVar, int nCBars, If_Obj_t ** ppLeaves, int nLeaves, int * pPrio )
00270 {
00271 Kit_DsdObj_t * pObj;
00272 If_Obj_t * pObjsNew[4][8], * pResPrev;
00273 int piLitsNew[8], pDecision[8];
00274 int i, k, nComps, nSize;
00275
00276
00277 nSize = (1 << nCBars);
00278 nComps = Lpk_FindHighest( ppNtks, piLits, nSize, pPrio, pDecision );
00279 if ( nComps == 0 )
00280 return If_Not( If_ManConst1(p->pIfMan) );
00281
00282
00283 if ( p->pPars->fVeryVerbose )
00284 printf( "Decision: " );
00285 for ( i = 0; i < nSize; i++ )
00286 {
00287 if ( pDecision[i] )
00288 {
00289 if ( p->pPars->fVeryVerbose )
00290 printf( "%d ", i );
00291 assert( piLits[i] >= 0 );
00292 pObj = Kit_DsdNtkObj( ppNtks[i], Kit_DsdLit2Var(piLits[i]) );
00293 if ( pObj == NULL )
00294 piLitsNew[i] = -2;
00295 else if ( pObj->Type == KIT_DSD_PRIME )
00296 piLitsNew[i] = pObj->pFans[0];
00297 else
00298 piLitsNew[i] = pObj->pFans[1];
00299 }
00300 else
00301 piLitsNew[i] = piLits[i];
00302 }
00303 if ( p->pPars->fVeryVerbose )
00304 printf( "\n" );
00305
00306
00307 pResPrev = Lpk_MapTreeMulti_rec( p, ppNtks, piLitsNew, piCofVar, nCBars, ppLeaves, nLeaves, pPrio );
00308
00309
00310 for ( i = 0; i < nSize; i++ )
00311 {
00312 if ( pDecision[i] )
00313 pObjsNew[nCBars][i] = Lpk_MapTree_rec( p, ppNtks[i], ppLeaves, piLits[i], pResPrev );
00314 else if ( piLits[i] == -1 )
00315 pObjsNew[nCBars][i] = If_ManConst1(p->pIfMan);
00316 else if ( piLits[i] == -2 )
00317 pObjsNew[nCBars][i] = If_Not( If_ManConst1(p->pIfMan) );
00318 else
00319 pObjsNew[nCBars][i] = pResPrev;
00320 }
00321
00322
00323 for ( k = nCBars; k > 0; k-- )
00324 {
00325 nSize /= 2;
00326 for ( i = 0; i < nSize; i++ )
00327 pObjsNew[k-1][i] = If_ManCreateMux( p->pIfMan, pObjsNew[k][2*i+0], pObjsNew[k][2*i+1], ppLeaves[piCofVar[k-1]] );
00328 }
00329 assert( nSize == 1 );
00330 return pObjsNew[0][0];
00331 }
00332
00344 If_Obj_t * Lpk_MapTreeMulti( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves )
00345 {
00346 static Counter = 0;
00347 If_Obj_t * pResult;
00348 Kit_DsdNtk_t * ppNtks[8] = {0}, * pTemp;
00349 Kit_DsdObj_t * pRoot;
00350 int piCofVar[4], pPrios[16], pFreqs[16] = {0}, piLits[16];
00351 int i, k, nCBars, nSize, nMemSize;
00352 unsigned * ppCofs[4][8], uSupport;
00353 char pTable[16][16] = {0};
00354 int fVerbose = p->pPars->fVeryVerbose;
00355
00356 Counter++;
00357
00358
00359
00360 nMemSize = Kit_TruthWordNum(nVars);
00361 ppCofs[0][0] = ALLOC( unsigned, 32 * nMemSize );
00362 nSize = 0;
00363 for ( i = 0; i < 4; i++ )
00364 for ( k = 0; k < 8; k++ )
00365 ppCofs[i][k] = ppCofs[0][0] + nMemSize * nSize++;
00366 assert( nSize == 32 );
00367
00368
00369 nCBars = Kit_DsdCofactoring( pTruth, nVars, piCofVar, p->pPars->nVarsShared, 0 );
00370
00371
00372
00373
00374
00375
00376 Kit_TruthCopy( ppCofs[0][0], pTruth, nVars );
00377
00378
00379 for ( k = 0; k < nCBars; k++ )
00380 {
00381 nSize = (1 << k);
00382 for ( i = 0; i < nSize; i++ )
00383 {
00384 Kit_TruthCofactor0New( ppCofs[k+1][2*i+0], ppCofs[k][i], nVars, piCofVar[k] );
00385 Kit_TruthCofactor1New( ppCofs[k+1][2*i+1], ppCofs[k][i], nVars, piCofVar[k] );
00386 }
00387 }
00388 nSize = (1 << nCBars);
00389
00390 for ( i = 0; i < nSize; i++ )
00391 {
00392 ppNtks[i] = Kit_DsdDecompose( ppCofs[nCBars][i], nVars );
00393 ppNtks[i] = Kit_DsdExpand( pTemp = ppNtks[i] );
00394 Kit_DsdNtkFree( pTemp );
00395 if ( fVerbose )
00396 {
00397 printf( "Cof%d%d: ", nCBars, i );
00398 Kit_DsdPrint( stdout, ppNtks[i] );
00399 }
00400 }
00401
00402
00403 for ( i = 0; i < nSize; i++ )
00404 {
00405 uSupport = Kit_TruthSupport( ppCofs[nCBars][i], nVars );
00406 for ( k = 0; k < nVars; k++ )
00407 if ( uSupport & (1<<k) )
00408 pFreqs[k]++;
00409 }
00410
00411
00412 for ( i = 0; i < nSize; i++ )
00413 {
00414 Kit_DsdGetSupports( ppNtks[i] );
00415 Lpk_CreateVarOrder( ppNtks[i], pTable );
00416 }
00417 Lpk_CreateCommonOrder( pTable, piCofVar, nCBars, pPrios, nVars, fVerbose );
00418
00419 for ( i = 0; i < nVars; i++ )
00420 pPrios[i] = pPrios[i] * 256 + (16 - pFreqs[i]) * 16 + i;
00421
00422 if ( fVerbose )
00423 printf( "After restructuring with priority:\n" );
00424
00425 if ( Counter == 1 )
00426 {
00427 int x = 0;
00428 }
00429
00430 for ( i = 0; i < nSize; i++ )
00431 {
00432 ppNtks[i] = Kit_DsdShrink( pTemp = ppNtks[i], pPrios );
00433 Kit_DsdNtkFree( pTemp );
00434 Kit_DsdGetSupports( ppNtks[i] );
00435 assert( ppNtks[i]->pSupps[0] <= 0xFFFF );
00436
00437 Kit_DsdRotate( ppNtks[i], pFreqs );
00438
00439 if ( fVerbose )
00440 {
00441 printf( "Cof%d%d: ", nCBars, i );
00442 Kit_DsdPrint( stdout, ppNtks[i] );
00443 }
00444 }
00445
00446 for ( i = 0; i < nSize; i++ )
00447 {
00448
00449 pRoot = Kit_DsdNtkRoot(ppNtks[i]);
00450 if ( pRoot->Type == KIT_DSD_CONST1 )
00451 piLits[i] = Kit_DsdLitIsCompl(ppNtks[i]->Root)? -2: -1;
00452 else if ( pRoot->Type == KIT_DSD_VAR )
00453 piLits[i] = Kit_DsdLitNotCond( pRoot->pFans[0], Kit_DsdLitIsCompl(ppNtks[i]->Root) );
00454 else
00455 piLits[i] = ppNtks[i]->Root;
00456 }
00457
00458
00459
00460 p->fCofactoring = 1;
00461 pResult = Lpk_MapTreeMulti_rec( p, ppNtks, piLits, piCofVar, nCBars, ppLeaves, nVars, pPrios );
00462 p->fCofactoring = 0;
00463
00464 if ( fVerbose )
00465 printf( "\n" );
00466
00467
00468 nSize = (1 << nCBars);
00469 for ( i = 0; i < nSize; i++ )
00470 Kit_DsdTruth( ppNtks[i], ppCofs[nCBars][i] );
00471
00472 for ( k = nCBars-1; k >= 0; k-- )
00473 {
00474 nSize = (1 << k);
00475 for ( i = 0; i < nSize; i++ )
00476 Kit_TruthMuxVar( ppCofs[k][i], ppCofs[k+1][2*i+0], ppCofs[k+1][2*i+1], nVars, piCofVar[k] );
00477 }
00478 if ( !Extra_TruthIsEqual( pTruth, ppCofs[0][0], nVars ) )
00479 printf( "Verification failed.\n" );
00480
00481
00482
00483 for ( i = 0; i < 8; i++ )
00484 if ( ppNtks[i] )
00485 Kit_DsdNtkFree( ppNtks[i] );
00486 free( ppCofs[0][0] );
00487
00488 return pResult;
00489 }
00490
00494
00495