/**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