blob: 4d1641238a9609b9f69c97df261aee553d49190c [file] [log] [blame]
/**CFile****************************************************************
FileName [darPrec.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Truth table precomputation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darPrec.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "darInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocated one-memory-chunk array.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char ** Dar_ArrayAlloc( int nCols, int nRows, int Size )
{
char ** pRes;
char * pBuffer;
int i;
assert( nCols > 0 && nRows > 0 && Size > 0 );
pBuffer = ABC_ALLOC( char, nCols * (sizeof(void *) + nRows * Size) );
pRes = (char **)pBuffer;
pRes[0] = pBuffer + nCols * sizeof(void *);
for ( i = 1; i < nCols; i++ )
pRes[i] = pRes[0] + i * nRows * Size;
return pRes;
}
/**Function********************************************************************
Synopsis [Computes the factorial.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
int Dar_Factorial( int n )
{
int i, Res = 1;
for ( i = 1; i <= n; i++ )
Res *= i;
return Res;
}
/**Function********************************************************************
Synopsis [Fills in the array of permutations.]
Description []
SideEffects []
SeeAlso []
******************************************************************************/
void Dar_Permutations_rec( char ** pRes, int nFact, int n, char Array[] )
{
char ** pNext;
int nFactNext;
int iTemp, iCur, iLast, k;
if ( n == 1 )
{
pRes[0][0] = Array[0];
return;
}
// get the next factorial
nFactNext = nFact / n;
// get the last entry
iLast = n - 1;
for ( iCur = 0; iCur < n; iCur++ )
{
// swap Cur and Last
iTemp = Array[iCur];
Array[iCur] = Array[iLast];
Array[iLast] = iTemp;
// get the pointer to the current section
pNext = pRes + (n - 1 - iCur) * nFactNext;
// set the last entry
for ( k = 0; k < nFactNext; k++ )
pNext[k][iLast] = Array[iLast];
// call recursively for this part
Dar_Permutations_rec( pNext, nFactNext, n - 1, Array );
// swap them back
iTemp = Array[iCur];
Array[iCur] = Array[iLast];
Array[iLast] = iTemp;
}
}
/**Function********************************************************************
Synopsis [Computes the set of all permutations.]
Description [The number of permutations in the array is n!. The number of
entries in each permutation is n. Therefore, the resulting array is a
two-dimentional array of the size: n! x n. To free the resulting array,
call ABC_FREE() on the pointer returned by this procedure.]
SideEffects []
SeeAlso []
******************************************************************************/
char ** Dar_Permutations( int n )
{
char Array[50];
char ** pRes;
int nFact, i;
// allocate memory
nFact = Dar_Factorial( n );
pRes = Dar_ArrayAlloc( nFact, n, sizeof(char) );
// fill in the permutations
for ( i = 0; i < n; i++ )
Array[i] = i;
Dar_Permutations_rec( pRes, nFact, n, Array );
// print the permutations
/*
{
int i, k;
for ( i = 0; i < nFact; i++ )
{
printf( "{" );
for ( k = 0; k < n; k++ )
printf( " %d", pRes[i][k] );
printf( " }\n" );
}
}
*/
return pRes;
}
/**Function*************************************************************
Synopsis [Permutes the given vector of minterms.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_TruthPermute_int( int * pMints, int nMints, char * pPerm, int nVars, int * pMintsP )
{
int m, v;
// clean the storage for minterms
memset( pMintsP, 0, sizeof(int) * nMints );
// go through minterms and add the variables
for ( m = 0; m < nMints; m++ )
for ( v = 0; v < nVars; v++ )
if ( pMints[m] & (1 << v) )
pMintsP[m] |= (1 << pPerm[v]);
}
/**Function*************************************************************
Synopsis [Permutes the function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Dar_TruthPermute( unsigned Truth, char * pPerms, int nVars, int fReverse )
{
unsigned Result;
int * pMints;
int * pMintsP;
int nMints;
int i, m;
assert( nVars < 6 );
nMints = (1 << nVars);
pMints = ABC_ALLOC( int, nMints );
pMintsP = ABC_ALLOC( int, nMints );
for ( i = 0; i < nMints; i++ )
pMints[i] = i;
Dar_TruthPermute_int( pMints, nMints, pPerms, nVars, pMintsP );
Result = 0;
if ( fReverse )
{
for ( m = 0; m < nMints; m++ )
if ( Truth & (1 << pMintsP[m]) )
Result |= (1 << m);
}
else
{
for ( m = 0; m < nMints; m++ )
if ( Truth & (1 << m) )
Result |= (1 << pMintsP[m]);
}
ABC_FREE( pMints );
ABC_FREE( pMintsP );
return Result;
}
/**Function*************************************************************
Synopsis [Changes the phase of the function.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Dar_TruthPolarize( unsigned uTruth, int Polarity, int nVars )
{
// elementary truth tables
static unsigned Signs[5] = {
0xAAAAAAAA, // 1010 1010 1010 1010 1010 1010 1010 1010
0xCCCCCCCC, // 1010 1010 1010 1010 1010 1010 1010 1010
0xF0F0F0F0, // 1111 0000 1111 0000 1111 0000 1111 0000
0xFF00FF00, // 1111 1111 0000 0000 1111 1111 0000 0000
0xFFFF0000 // 1111 1111 1111 1111 0000 0000 0000 0000
};
unsigned uTruthRes, uCof0, uCof1;
int nMints, Shift, v;
assert( nVars < 6 );
nMints = (1 << nVars);
uTruthRes = uTruth;
for ( v = 0; v < nVars; v++ )
if ( Polarity & (1 << v) )
{
uCof0 = uTruth & ~Signs[v];
uCof1 = uTruth & Signs[v];
Shift = (1 << v);
uCof0 <<= Shift;
uCof1 >>= Shift;
uTruth = uCof0 | uCof1;
}
return uTruth;
}
/**Function*************************************************************
Synopsis [Computes NPN canonical forms for 4-variable functions.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Dar_Truth4VarNPN( unsigned short ** puCanons, char ** puPhases, char ** puPerms, unsigned char ** puMap )
{
unsigned short * uCanons;
unsigned char * uMap;
unsigned uTruth, uPhase, uPerm;
char ** pPerms4, * uPhases, * uPerms;
int nFuncs, nClasses;
int i, k;
nFuncs = (1 << 16);
uCanons = ABC_CALLOC( unsigned short, nFuncs );
uPhases = ABC_CALLOC( char, nFuncs );
uPerms = ABC_CALLOC( char, nFuncs );
uMap = ABC_CALLOC( unsigned char, nFuncs );
pPerms4 = Dar_Permutations( 4 );
nClasses = 1;
nFuncs = (1 << 15);
for ( uTruth = 1; uTruth < (unsigned)nFuncs; uTruth++ )
{
// skip already assigned
if ( uCanons[uTruth] )
{
assert( uTruth > uCanons[uTruth] );
uMap[~uTruth & 0xFFFF] = uMap[uTruth] = uMap[uCanons[uTruth]];
continue;
}
uMap[uTruth] = nClasses++;
for ( i = 0; i < 16; i++ )
{
uPhase = Dar_TruthPolarize( uTruth, i, 4 );
for ( k = 0; k < 24; k++ )
{
uPerm = Dar_TruthPermute( uPhase, pPerms4[k], 4, 0 );
if ( uCanons[uPerm] == 0 )
{
uCanons[uPerm] = uTruth;
uPhases[uPerm] = i;
uPerms[uPerm] = k;
uMap[uPerm] = uMap[uTruth];
uPerm = ~uPerm & 0xFFFF;
uCanons[uPerm] = uTruth;
uPhases[uPerm] = i | 16;
uPerms[uPerm] = k;
uMap[uPerm] = uMap[uTruth];
}
else
assert( uCanons[uPerm] == uTruth );
}
uPhase = Dar_TruthPolarize( ~uTruth & 0xFFFF, i, 4 );
for ( k = 0; k < 24; k++ )
{
uPerm = Dar_TruthPermute( uPhase, pPerms4[k], 4, 0 );
if ( uCanons[uPerm] == 0 )
{
uCanons[uPerm] = uTruth;
uPhases[uPerm] = i;
uPerms[uPerm] = k;
uMap[uPerm] = uMap[uTruth];
uPerm = ~uPerm & 0xFFFF;
uCanons[uPerm] = uTruth;
uPhases[uPerm] = i | 16;
uPerms[uPerm] = k;
uMap[uPerm] = uMap[uTruth];
}
else
assert( uCanons[uPerm] == uTruth );
}
}
}
for ( uTruth = 1; uTruth < 0xffff; uTruth++ )
assert( uMap[uTruth] != 0 );
uPhases[(1<<16)-1] = 16;
assert( nClasses == 222 );
ABC_FREE( pPerms4 );
if ( puCanons )
*puCanons = uCanons;
else
ABC_FREE( uCanons );
if ( puPhases )
*puPhases = uPhases;
else
ABC_FREE( uPhases );
if ( puPerms )
*puPerms = uPerms;
else
ABC_FREE( uPerms );
if ( puMap )
*puMap = uMap;
else
ABC_FREE( uMap );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END