blob: ae6d55047aee7820c80dddd585e6a82aaebcc706 [file] [log] [blame]
/**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->positionToSwap1<x->positionToSwap2)
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<size;i++)
if((x>>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<<var)-1;
x->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