/**CFile**************************************************************** FileName [luckySimple.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Semi-canonical form computation package.] Synopsis [Truth table minimization procedures.] Author [Jake] Date [Started - August 2012] ***********************************************************************/ #include "luckyInt.h" ABC_NAMESPACE_IMPL_START static swapInfo* setSwapInfoPtr(int varsN) { int i; swapInfo* x = (swapInfo*) malloc(sizeof(swapInfo)); x->posArray = (varInfo*) malloc (sizeof(varInfo)*(varsN+2)); x->realArray = (int*) malloc (sizeof(int)*(varsN+2)); x->varN = varsN; x->realArray[0]=varsN+100; for(i=1;i<=varsN;i++) { x->posArray[i].position=i; x->posArray[i].direction=-1; x->realArray[i]=i; } x->realArray[varsN+1]=varsN+10; return x; } static void freeSwapInfoPtr(swapInfo* x) { free(x->posArray); free(x->realArray); free(x); } int nextSwap(swapInfo* x) { int i,j,temp; for(i=x->varN;i>1;i--) { if( i > x->realArray[x->posArray[i].position + x->posArray[i].direction] ) { x->posArray[i].position = x->posArray[i].position + x->posArray[i].direction; temp = x->realArray[x->posArray[i].position]; x->realArray[x->posArray[i].position] = i; x->realArray[x->posArray[i].position - x->posArray[i].direction] = temp; x->posArray[temp].position = x->posArray[i].position - x->posArray[i].direction; for(j=x->varN;j>i;j--) { x->posArray[j].direction = x->posArray[j].direction * -1; } x->positionToSwap1 = x->posArray[temp].position - 1; x->positionToSwap2 = x->posArray[i].position - 1; return 1; } } return 0; } void fillInSwapArray(permInfo* pi) { int counter=pi->totalSwaps-1; swapInfo* x= setSwapInfoPtr(pi->varN); while(nextSwap(x)==1) { if(x->positionToSwap1positionToSwap2) pi->swapArray[counter--]=x->positionToSwap1; else pi->swapArray[counter--]=x->positionToSwap2; } freeSwapInfoPtr(x); } int oneBitPosition(int x, int size) { int i; for(i=0;i>i)&1) return i; return -1; } void fillInFlipArray(permInfo* pi) { int i, temp=0, grayNumber; for(i=1;i<=pi->totalFlips;i++) { grayNumber = i^(i>>1); pi->flipArray[pi->totalFlips-i]=oneBitPosition(temp^grayNumber, pi->varN); temp = grayNumber; } } static inline int factorial(int n) { return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n; } permInfo* setPermInfoPtr(int var) { permInfo* x; x = (permInfo*) malloc(sizeof(permInfo)); x->flipCtr=0; x->varN = var; x->totalFlips=(1<swapCtr=0; x->totalSwaps=factorial(var)-1; x->flipArray = (int*) malloc(sizeof(int)*x->totalFlips); x->swapArray = (int*) malloc(sizeof(int)*x->totalSwaps); fillInSwapArray(x); fillInFlipArray(x); return x; } void freePermInfoPtr(permInfo* x) { free(x->flipArray); free(x->swapArray); free(x); } static inline void minWord(word* a, word* b, word* minimal, int nVars) { if(memCompare(a, b, nVars) == -1) Kit_TruthCopy_64bit( minimal, a, nVars ); else Kit_TruthCopy_64bit( minimal, b, nVars ); } static inline void minWord3(word* a, word* b, word* minimal, int nVars) { if (memCompare(a, b, nVars) <= 0) { if (memCompare(a, minimal, nVars) < 0) Kit_TruthCopy_64bit( minimal, a, nVars ); else return ; } if (memCompare(b, minimal, nVars) <= 0) Kit_TruthCopy_64bit( minimal, b, nVars ); } static inline void minWord1(word* a, word* minimal, int nVars) { if (memCompare(a, minimal, nVars) <= 0) Kit_TruthCopy_64bit( minimal, a, nVars ); } void simpleMinimal(word* x, word* pAux,word* minimal, permInfo* pi, int nVars) { int i,j=0; Kit_TruthCopy_64bit( pAux, x, nVars ); Kit_TruthNot_64bit( x, nVars ); minWord(x, pAux, minimal, nVars); for(i=pi->totalSwaps-1;i>=0;i--) { Kit_TruthSwapAdjacentVars_64bit(x, nVars, pi->swapArray[i]); Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, pi->swapArray[i]); minWord3(x, pAux, minimal, nVars); } for(j=pi->totalFlips-1;j>=0;j--) { Kit_TruthSwapAdjacentVars_64bit(x, nVars, 0); Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, 0); Kit_TruthChangePhase_64bit(x, nVars, pi->flipArray[j]); Kit_TruthChangePhase_64bit(pAux, nVars, pi->flipArray[j]); minWord3(x, pAux, minimal, nVars); for(i=pi->totalSwaps-1;i>=0;i--) { Kit_TruthSwapAdjacentVars_64bit(x, nVars, pi->swapArray[i]); Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, pi->swapArray[i]); minWord3(x, pAux, minimal, nVars); } } Kit_TruthCopy_64bit( x, minimal, nVars ); } /** * pGroups: we assume that the variables are merged into adjacent groups, * the size of each group is stored in pGroups * nGroups: the number of groups * * pis: we compute all permInfos from 0 to nVars (incl.) */ void simpleMinimalGroups(word* x, word* pAux, word* minimal, int* pGroups, int nGroups, permInfo** pis, int nVars, int fFlipOutput, int fFlipInput) { /* variables */ int i, j, o, nn; permInfo* pi; int * a, * c, * m; /* reorder groups and calculate group offsets */ int * offset = ABC_ALLOC( int, nGroups ); o = 0; j = 0; for ( i = 0; i < nGroups; ++i ) { offset[j] = o; o += pGroups[j]; ++j; } if ( fFlipOutput ) { /* keep regular and inverted version of x */ Kit_TruthCopy_64bit( pAux, x, nVars ); Kit_TruthNot_64bit( x, nVars ); minWord(x, pAux, minimal, nVars); } else { Kit_TruthCopy_64bit( minimal, x, nVars ); } /* iterate through all combinations of pGroups using mixed radix enumeration */ nn = ( nGroups << 1 ) + 1; a = ABC_ALLOC( int, nn ); c = ABC_ALLOC( int, nn ); m = ABC_ALLOC( int, nn ); /* fill a and m arrays */ m[0] = 2; for ( i = 1; i <= nGroups; ++i ) { m[i] = pis[pGroups[i - 1]]->totalFlips + 1; } for ( i = 1; i <= nGroups; ++i ) { m[nGroups + i] = pis[pGroups[i - 1]]->totalSwaps + 1; } for ( i = 0; i < nn; ++i ) { a[i] = c[i] = 0; } while ( 1 ) { /* consider all flips */ for ( i = 1; i <= nGroups; ++i ) { if ( !c[i] ) { continue; } if ( !fFlipInput && pGroups[i - 1] == 1 ) { continue; } pi = pis[pGroups[i - 1]]; j = a[i] == 0 ? 0 : pi->totalFlips - a[i]; Kit_TruthChangePhase_64bit(x, nVars, offset[i - 1] + pi->flipArray[j]); if ( fFlipOutput ) { Kit_TruthChangePhase_64bit(pAux, nVars, offset[i - 1] + pi->flipArray[j]); minWord3(x, pAux, minimal, nVars); } else { minWord1(x, minimal, nVars); } } /* consider all swaps */ for ( i = 1; i <= nGroups; ++i ) { if ( !c[nGroups + i] ) { continue; } if ( pGroups[i - 1] == 1 ) { continue; } pi = pis[pGroups[i - 1]]; if ( a[nGroups + i] == pi->totalSwaps ) { j = 0; } else { j = pi->swapArray[pi->totalSwaps - a[nGroups + i] - 1]; } Kit_TruthSwapAdjacentVars_64bit(x, nVars, offset[i - 1] + j); if ( fFlipOutput ) { Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, offset[i - 1] + j); minWord3(x, pAux, minimal, nVars); } else { minWord1(x, minimal, nVars); } } /* update a's */ memset(c, 0, sizeof(int) * nn); j = nn - 1; while ( a[j] == m[j] - 1 ) { c[j] = 1; a[j--] = 0; } /* done? */ if ( j == 0 ) { break; } c[j] = 1; a[j]++; } ABC_FREE( offset ); ABC_FREE( a ); ABC_FREE( c ); ABC_FREE( m ); Kit_TruthCopy_64bit( x, minimal, nVars ); } ABC_NAMESPACE_IMPL_END