Commit 49c57999 by Alan Mishchenko

Several improvements to command 'testnpn'.

parent f85db9dd
...@@ -4926,10 +4926,10 @@ usage: ...@@ -4926,10 +4926,10 @@ usage:
Abc_Print( -2, "\t testbench for computing semi-canonical forms of Boolean functions\n" ); Abc_Print( -2, "\t testbench for computing semi-canonical forms of Boolean functions\n" );
Abc_Print( -2, "\t-A <num> : semi-caninical form computation algorithm [default = %d]\n", NpnType ); Abc_Print( -2, "\t-A <num> : semi-caninical form computation algorithm [default = %d]\n", NpnType );
Abc_Print( -2, "\t 0: none (reading and writing the file)\n" ); Abc_Print( -2, "\t 0: none (reading and writing the file)\n" );
Abc_Print( -2, "\t 1: semi-canonical form by counting 1s in cofactors\n" ); Abc_Print( -2, "\t 1: exact canonical form (work only for 6 variables)\n" );
Abc_Print( -2, "\t 2: semi-canonical form by minimizing truth table value\n" ); Abc_Print( -2, "\t 2: semi-canonical form by counting 1s in cofactors\n" );
Abc_Print( -2, "\t 3: exact canonical form (work only for 6 variables)\n" ); Abc_Print( -2, "\t 3: semi-canonical form by minimizing truth table value\n" );
Abc_Print( -2, "\t 4: heuristic canonical form (work only for 6 variables)\n" ); Abc_Print( -2, "\t 4: hybrid semi-canonical form (work only for 6 variables)\n" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t-h : print the command usage\n");
return 1; return 1;
......
...@@ -114,12 +114,10 @@ void Abc_TruthReadHex( word * pTruth, char * pString, int nVars ) ...@@ -114,12 +114,10 @@ void Abc_TruthReadHex( word * pTruth, char * pString, int nVars )
void Abc_TruthWriteHex( FILE * pFile, word * pTruth, int nVars ) void Abc_TruthWriteHex( FILE * pFile, word * pTruth, int nVars )
{ {
int nDigits, Digit, k; int nDigits, Digit, k;
// write hexadecimal digits in the reverse order
// (the last symbol in the string is the least significant digit)
nDigits = (1 << (nVars-2)); nDigits = (1 << (nVars-2));
for ( k = 0; k < nDigits; k++ ) for ( k = 0; k < nDigits; k++ )
{ {
Digit = Abc_TruthGetHex( pTruth, nDigits - 1 - k ); Digit = Abc_TruthGetHex( pTruth, k );
assert( Digit >= 0 && Digit < 16 ); assert( Digit >= 0 && Digit < 16 );
Abc_TruthWriteHexDigit( pFile, Digit ); Abc_TruthWriteHexDigit( pFile, Digit );
} }
...@@ -145,10 +143,11 @@ Abc_TtStore_t * Abc_TruthStoreAlloc( int nVars, int nFuncs ) ...@@ -145,10 +143,11 @@ Abc_TtStore_t * Abc_TruthStoreAlloc( int nVars, int nFuncs )
p->nVars = nVars; p->nVars = nVars;
p->nWords = (nVars < 7) ? 1 : (1 << (nVars-6)); p->nWords = (nVars < 7) ? 1 : (1 << (nVars-6));
p->nFuncs = nFuncs; p->nFuncs = nFuncs;
// alloc array of 'nFuncs' pointers to truth tables
p->pFuncs = (word **)malloc( sizeof(word *) * p->nFuncs );
// alloc storage for 'nFuncs' truth tables as one chunk of memory // alloc storage for 'nFuncs' truth tables as one chunk of memory
p->pFuncs[0] = (word *)calloc( sizeof(word), p->nFuncs * p->nWords ); p->pFuncs = (word **)malloc( (sizeof(word *) + sizeof(word) * p->nWords) * p->nFuncs );
// assign and clean the truth table storage
p->pFuncs[0] = (word *)(p->pFuncs + p->nFuncs);
memset( p->pFuncs[0], 0, sizeof(word) * p->nWords * p->nFuncs );
// split it up into individual truth tables // split it up into individual truth tables
for ( i = 1; i < p->nFuncs; i++ ) for ( i = 1; i < p->nFuncs; i++ )
p->pFuncs[i] = p->pFuncs[i-1] + p->nWords; p->pFuncs[i] = p->pFuncs[i-1] + p->nWords;
...@@ -156,7 +155,6 @@ Abc_TtStore_t * Abc_TruthStoreAlloc( int nVars, int nFuncs ) ...@@ -156,7 +155,6 @@ Abc_TtStore_t * Abc_TruthStoreAlloc( int nVars, int nFuncs )
} }
void Abc_TtStoreFree( Abc_TtStore_t * p ) void Abc_TtStoreFree( Abc_TtStore_t * p )
{ {
free( p->pFuncs[0] );
free( p->pFuncs ); free( p->pFuncs );
free( p ); free( p );
} }
...@@ -308,7 +306,7 @@ void Abc_TruthStoreRead( char * pFileName, Abc_TtStore_t * p ) ...@@ -308,7 +306,7 @@ void Abc_TruthStoreRead( char * pFileName, Abc_TtStore_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_TruthStoreWrite( char * pFileName, Abc_TtStore_t * p ) void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p )
{ {
FILE * pFile; FILE * pFile;
int i; int i;
...@@ -380,7 +378,7 @@ void Abc_TtStoreTest( char * pFileName ) ...@@ -380,7 +378,7 @@ void Abc_TtStoreTest( char * pFileName )
return; return;
// write into another file // write into another file
Abc_TruthStoreWrite( pFileOutput, p ); Abc_TtStoreWrite( pFileOutput, p );
// delete data-structure // delete data-structure
Abc_TtStoreFree( p ); Abc_TtStoreFree( p );
......
...@@ -49,7 +49,7 @@ struct Abc_TtStore_t_ ...@@ -49,7 +49,7 @@ struct Abc_TtStore_t_
extern Abc_TtStore_t * Abc_TtStoreLoad( char * pFileName ); extern Abc_TtStore_t * Abc_TtStoreLoad( char * pFileName );
extern void Abc_TtStoreFree( Abc_TtStore_t * p ); extern void Abc_TtStoreFree( Abc_TtStore_t * p );
extern void Abc_TtStoreTest( char * pFileName ); extern void Abc_TtStoreWrite( char * pFileName, Abc_TtStore_t * p );
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
...@@ -67,20 +67,19 @@ extern void Abc_TtStoreTest( char * pFileName ); ...@@ -67,20 +67,19 @@ extern void Abc_TtStoreTest( char * pFileName );
***********************************************************************/ ***********************************************************************/
int nWords = 0; // unfortunate global variable int nWords = 0; // unfortunate global variable
int Abc_TruthCompare( word * p1, word * p2 ) { return memcmp(p1, p2, sizeof(word) * nWords); } int Abc_TruthCompare( word ** p1, word ** p2 ) { return memcmp(*p1, *p2, sizeof(word) * nWords); }
int Abc_TruthNpnCountUnique( Abc_TtStore_t * p ) int Abc_TruthNpnCountUnique( Abc_TtStore_t * p )
{ {
int i, nUnique; int i, k;
// sort them by value // sort them by value
nWords = p->nWords; nWords = p->nWords;
assert( nWords > 0 ); assert( nWords > 0 );
qsort( (void *)p->pFuncs[0], p->nFuncs, nWords * sizeof(word), (int(*)(const void *,const void *))Abc_TruthCompare ); qsort( (void *)p->pFuncs, p->nFuncs, sizeof(word *), (int(*)(const void *,const void *))Abc_TruthCompare );
// count the number of unqiue functions // count the number of unqiue functions
nUnique = p->nFuncs; for ( i = k = 1; i < p->nFuncs; i++ )
for ( i = 1; i < p->nFuncs; i++ ) if ( memcmp( p->pFuncs[i-1], p->pFuncs[i], sizeof(word) * nWords ) )
if ( !memcmp( p->pFuncs[i-1], p->pFuncs[i], sizeof(word) * nWords ) ) p->pFuncs[k++] = p->pFuncs[i];
nUnique--; return (p->nFuncs = k);
return nUnique;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -104,14 +103,16 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) ...@@ -104,14 +103,16 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
int i;//, nFuncs = 0; int i;//, nFuncs = 0;
char * pAlgoName = NULL; char * pAlgoName = NULL;
if ( NpnType == 1 ) if ( NpnType == 0 )
pAlgoName = "counting 1s "; pAlgoName = "uniqifying ";
else if ( NpnType == 1 )
pAlgoName = "exact NPN ";
else if ( NpnType == 2 ) else if ( NpnType == 2 )
pAlgoName = "minimizing TT"; pAlgoName = "counting 1s ";
else if ( NpnType == 3 ) else if ( NpnType == 3 )
pAlgoName = "exact NPN "; pAlgoName = "minimizing TT";
else if ( NpnType == 4 ) else if ( NpnType == 4 )
pAlgoName = "heuristic NPN"; pAlgoName = "hybrid NPN ";
assert( p->nVars <= 16 ); assert( p->nVars <= 16 );
if ( pAlgoName ) if ( pAlgoName )
...@@ -120,29 +121,17 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) ...@@ -120,29 +121,17 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
if ( fVerbose ) if ( fVerbose )
printf( "\n" ); printf( "\n" );
if ( NpnType == 1 ) if ( NpnType == 0 )
{
for ( i = 0; i < p->nFuncs; i++ )
{
if ( fVerbose )
printf( "%7d : ", i );
Kit_TruthSemiCanonicize( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm, pStore );
if ( fVerbose )
Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
}
}
else if ( NpnType == 2 )
{ {
for ( i = 0; i < p->nFuncs; i++ ) for ( i = 0; i < p->nFuncs; i++ )
{ {
if ( fVerbose ) if ( fVerbose )
printf( "%7d : ", i ); printf( "%7d : ", i );
Kit_TruthSemiCanonicize_new( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm );
if ( fVerbose ) if ( fVerbose )
Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" ); Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
} }
} }
else if ( NpnType == 3 ) else if ( NpnType == 1 )
{ {
int * pComp = Extra_GreyCodeSchedule( p->nVars ); int * pComp = Extra_GreyCodeSchedule( p->nVars );
int * pPerm = Extra_PermSchedule( p->nVars ); int * pPerm = Extra_PermSchedule( p->nVars );
...@@ -162,6 +151,28 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) ...@@ -162,6 +151,28 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
ABC_FREE( pComp ); ABC_FREE( pComp );
ABC_FREE( pPerm ); ABC_FREE( pPerm );
} }
else if ( NpnType == 2 )
{
for ( i = 0; i < p->nFuncs; i++ )
{
if ( fVerbose )
printf( "%7d : ", i );
Kit_TruthSemiCanonicize( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm, pStore );
if ( fVerbose )
Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
}
}
else if ( NpnType == 3 )
{
for ( i = 0; i < p->nFuncs; i++ )
{
if ( fVerbose )
printf( "%7d : ", i );
Kit_TruthSemiCanonicize_new( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm );
if ( fVerbose )
Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
}
}
else if ( NpnType == 4 ) else if ( NpnType == 4 )
{ {
if ( p->nVars == 6 ) if ( p->nVars == 6 )
...@@ -200,6 +211,7 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) ...@@ -200,6 +211,7 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
void Abc_TruthNpnTest( char * pFileName, int NpnType, int fVerbose ) void Abc_TruthNpnTest( char * pFileName, int NpnType, int fVerbose )
{ {
Abc_TtStore_t * p; Abc_TtStore_t * p;
char * pFileNameOut;
// read info from file // read info from file
p = Abc_TtStoreLoad( pFileName ); p = Abc_TtStoreLoad( pFileName );
...@@ -209,6 +221,12 @@ void Abc_TruthNpnTest( char * pFileName, int NpnType, int fVerbose ) ...@@ -209,6 +221,12 @@ void Abc_TruthNpnTest( char * pFileName, int NpnType, int fVerbose )
// consider functions from the file // consider functions from the file
Abc_TruthNpnPerform( p, NpnType, fVerbose ); Abc_TruthNpnPerform( p, NpnType, fVerbose );
// write the result
pFileNameOut = Extra_FileNameGenericAppend( pFileName, "_out.txt" );
Abc_TtStoreWrite( pFileNameOut, p );
if ( fVerbose )
printf( "The resulting functions are written into file \"%s\".\n", pFileNameOut );
// delete data-structure // delete data-structure
Abc_TtStoreFree( p ); Abc_TtStoreFree( p );
// printf( "Finished computing canonical forms for functions from file \"%s\".\n", pFileName ); // printf( "Finished computing canonical forms for functions from file \"%s\".\n", pFileName );
...@@ -230,9 +248,7 @@ int Abc_NpnTest( char * pFileName, int NpnType, int fVerbose ) ...@@ -230,9 +248,7 @@ int Abc_NpnTest( char * pFileName, int NpnType, int fVerbose )
{ {
if ( fVerbose ) if ( fVerbose )
printf( "Using truth tables from file \"%s\"...\n", pFileName ); printf( "Using truth tables from file \"%s\"...\n", pFileName );
if ( NpnType == 0 ) if ( NpnType >= 0 && NpnType <= 4 )
Abc_TtStoreTest( pFileName );
else if ( NpnType >= 1 && NpnType <= 4 )
Abc_TruthNpnTest( pFileName, NpnType, fVerbose ); Abc_TruthNpnTest( pFileName, NpnType, fVerbose );
else else
printf( "Unknown canonical form value (%d).\n", NpnType ); printf( "Unknown canonical form value (%d).\n", NpnType );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment