diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0ddca29d4..badebec0d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -89,6 +89,7 @@ static int Abc_CommandPrintMffc ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandPrintFactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintLevel ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrintSupport ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrintNpn ( Abc_Frame_t * pAbc, int argc, char ** argv ); #ifdef ABC_USE_CUDD static int Abc_CommandPrintMint ( Abc_Frame_t * pAbc, int argc, char ** argv ); #endif @@ -910,6 +911,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Printing", "print_level", Abc_CommandPrintLevel, 0 ); Cmd_CommandAdd( pAbc, "Printing", "psu", Abc_CommandPrintSupport, 0 ); Cmd_CommandAdd( pAbc, "Printing", "print_supp", Abc_CommandPrintSupport, 0 ); + Cmd_CommandAdd( pAbc, "Printing", "print_npn", Abc_CommandPrintNpn, 0 ); #ifdef ABC_USE_CUDD Cmd_CommandAdd( pAbc, "Printing", "print_mint", Abc_CommandPrintMint, 0 ); #endif @@ -2278,6 +2280,61 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandPrintNpn( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Dau_PrintNpnFunctions( word * p, int nVars, int fVerbose ); + char * pTruthStr = NULL; + word pTruth[16] = {0}; + int c, nVars, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( globalUtilOptind != argc-1 ) + { + Abc_Print( -1, "The command expects the truth table on the command line.\n" ); + goto usage; + } + pTruthStr = argv[globalUtilOptind]; + nVars = Abc_TtReadHex( pTruth, pTruthStr ); + assert( nVars <= 10 ); + Dau_PrintNpnFunctions( pTruth, nVars, fVerbose ); + return 0; + +usage: + Abc_Print( -2, "usage: print_npn [-vh] \n" ); + Abc_Print( -2, "\t prints the NPN members of the given function\n" ); + Abc_Print( -2, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t : the truth table in hexadecimal notation\n"); + + return 1; +} + + + + /**Function************************************************************* Synopsis [] diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index d94e9bfe2..2d0422401 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1640,7 +1640,7 @@ static inline void Abc_TtPrintBits2( word * pTruth, int nBits ) int k; for ( k = nBits-1; k >= 0; k-- ) printf( "%d", Abc_InfoHasBit( (unsigned *)pTruth, k ) ); - printf( "\n" ); + //printf( "\n" ); } static inline void Abc_TtPrintBinary( word * pTruth, int nVars ) { diff --git a/src/opt/dau/dauNpn.c b/src/opt/dau/dauNpn.c index a654695c5..96f81c508 100644 --- a/src/opt/dau/dauNpn.c +++ b/src/opt/dau/dauNpn.c @@ -859,6 +859,85 @@ Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose ) return vTtMem; } +/**Function************************************************************* + + Synopsis [Function enumeration.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Dau_PrintNpnFunction( Vec_Mem_t * vTtMem, int nFuncs, word * pCopy, int nVars, int uPhase, int * pPerm, int fVerbose ) +{ + int nWords = Abc_Truth6WordNum(nVars); + if ( fVerbose ) { + printf( "%6d : ", nFuncs ); + Abc_TtPrintBits2((word *)&uPhase, nVars); + printf( " " ); + for ( int v = nVars-1; v >= 0; v-- ) + printf( " %d", pPerm[v] ); + printf( " F = " ); + Abc_TtPrintHexRev( stdout, pCopy, nVars ); + } + int Pos = Vec_MemHashInsert( vTtMem, pCopy ); + Abc_TtNot( pCopy, nWords ); + if ( fVerbose ) { + printf( " (%05d)", Pos ); + printf( " ~F = " ); + Abc_TtPrintHexRev( stdout, pCopy, nVars ); + } + int Neg = Vec_MemHashInsert( vTtMem, pCopy ); + Abc_TtNot( pCopy, nWords ); + if ( fVerbose ) { + printf( " (%05d)", Neg ); + printf( "\n" ); + } +} +void Dau_PrintNpnFunctions( word * p, int nVars, int fVerbose ) +{ + int nWords = Abc_Truth6WordNum(nVars); + Vec_Mem_t * vTtMem = Vec_MemAllocForTTSimple( nVars ); + word * pCopy = ABC_ALLOC( word, nWords ); + word * pBest = ABC_ALLOC( word, nWords ); + Abc_TtCopy( pCopy, p, nWords, 0 ); + Abc_TtCopy( pBest, p, nWords, 0 ); + int nPerms = Extra_Factorial( nVars ); + int nMints = 1 << nVars; + int * pPerm = Extra_PermSchedule( nVars ); + int * pComp = Extra_GreyCodeSchedule( nVars ); + int m, i, k, nFuncs = 0; + int uVarPhase = 0; + int pVarPerm[32]; + printf( "The number of NPN configurations is %d = %d complementations * %d permutations * 2 output polarities.\n", nMints*nPerms*2, nMints, nPerms ); + for ( i = 0; i < nVars; i++ ) + pVarPerm[i] = i; + for ( m = 0; m < nMints; m++ ) { + for ( k = 0; k < nPerms; k++ ) { + if ( Abc_TtCompare(pBest, pCopy, nWords) == 1 ) + Abc_TtCopy( pBest, pCopy, nWords, 0 ); + Dau_PrintNpnFunction( vTtMem, nFuncs++, pCopy, nVars, uVarPhase, pVarPerm, fVerbose ); + Abc_TtSwapAdjacent( pCopy, nWords, pPerm[k] ); + ABC_SWAP( int, pVarPerm[pPerm[k]], pVarPerm[pPerm[k]+1] ); + } + if ( fVerbose ) printf( "\n" ); + Abc_TtFlip( pCopy, nWords, pComp[m] ); + uVarPhase ^= 1 << pComp[m]; + } + assert( Abc_TtEqual(pCopy, p, nWords) ); + printf( "The number of unique functions %d (out of %d). Frequency = %d. Representative: ", Vec_MemEntryNum(vTtMem), nMints*nPerms*2, nMints*nPerms*2/Vec_MemEntryNum(vTtMem) ); + Abc_TtPrintHexRev( stdout, pBest, nVars ); + printf( "\n" ); + ABC_FREE( pPerm ); + ABC_FREE( pComp ); + ABC_FREE( pCopy ); + ABC_FREE( pBest ); + Vec_MemHashFree( vTtMem ); + Vec_MemFree( vTtMem ); +} + /**Function************************************************************* Synopsis [Compute NPN class members.]