Commit 12c776ed by Alan Mishchenko

Added new algorithm for NPN semi-canonical form computation.

parent 261bd7f8
......@@ -4928,7 +4928,8 @@ usage:
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 2: semi-canonical form by minimizing truth table value\n" );
Abc_Print( -2, "\t 3: exact canonical form (slow for more than 6 variables)\n" );
Abc_Print( -2, "\t 3: exact canonical form (work only for 6 variables)\n" );
Abc_Print( -2, "\t 4: heuristic 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-h : print the command usage\n");
return 1;
......
......@@ -110,6 +110,8 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
pAlgoName = "minimizing TT";
else if ( NpnType == 3 )
pAlgoName = "exact NPN ";
else if ( NpnType == 4 )
pAlgoName = "heuristic NPN";
assert( p->nVars <= 16 );
if ( pAlgoName )
......@@ -150,7 +152,7 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
{
if ( fVerbose )
printf( "%7d : ", i );
*((word *)p->pFuncs[i]) = Extra_Truth6Minimum( *((word *)p->pFuncs[i]), pComp, pPerm );
*((word *)p->pFuncs[i]) = Extra_Truth6MinimumExact( *((word *)p->pFuncs[i]), pComp, pPerm );
if ( fVerbose )
Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
}
......@@ -160,6 +162,23 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
ABC_FREE( pComp );
ABC_FREE( pPerm );
}
else if ( NpnType == 4 )
{
if ( p->nVars == 6 )
{
for ( i = 0; i < p->nFuncs; i++ )
{
if ( fVerbose )
printf( "%7d : ", i );
Kit_TruthSemiCanonicize( (unsigned *)p->pFuncs[i], pAux, p->nVars, pCanonPerm, pStore );
*((word *)p->pFuncs[i]) = Extra_Truth6MinimumHeuristic( *((word *)p->pFuncs[i]) );
if ( fVerbose )
Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), printf( "\n" );
}
}
else
printf( "This feature only works for 6-variable functions.\n" );
}
else assert( 0 );
clk = clock() - clk;
......@@ -213,7 +232,7 @@ int Abc_NpnTest( char * pFileName, int NpnType, int fVerbose )
printf( "Using truth tables from file \"%s\"...\n", pFileName );
if ( NpnType == 0 )
Abc_TtStoreTest( pFileName );
else if ( NpnType >= 1 && NpnType <= 3 )
else if ( NpnType >= 1 && NpnType <= 4 )
Abc_TruthNpnTest( pFileName, NpnType, fVerbose );
else
printf( "Unknown canonical form value (%d).\n", NpnType );
......
......@@ -1685,7 +1685,7 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
// canonicize phase
for ( i = 0; i < nVars; i++ )
{
if ( pStore[2*i+0] <= pStore[2*i+1] )
if ( pStore[2*i+0] >= pStore[2*i+1] )
continue;
uCanonPhase |= (1 << i);
Temp = pStore[2*i+0];
......@@ -1703,7 +1703,7 @@ unsigned Kit_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux, int nVars,
fChange = 0;
for ( i = 0; i < nVars-1; i++ )
{
if ( pStore[2*i] <= pStore[2*(i+1)] )
if ( pStore[2*i] >= pStore[2*(i+1)] )
continue;
Counter++;
fChange = 1;
......
......@@ -203,7 +203,8 @@ extern void Extra_BubbleSort( int Order[], int Costs[], int nSize, int fI
/* complementation/permutation generation */
extern int * Extra_GreyCodeSchedule( int n );
extern int * Extra_PermSchedule( int n );
extern word Extra_Truth6Minimum( word t, int * pComp, int * pPerm );
extern word Extra_Truth6MinimumExact( word t, int * pComp, int * pPerm );
extern word Extra_Truth6MinimumHeuristic( word t );
/*=== extraUtilCanon.c ========================================================*/
......
......@@ -2283,7 +2283,7 @@ static inline word Extra_Truth6ChangePhase( word t, int v )
assert( v < 6 );
return ((t & ~Truth6[v]) << (1 << v)) | ((t & Truth6[v]) >> (1 << v));
}
word Extra_Truth6Minimum( word t, int * pComp, int * pPerm )
word Extra_Truth6MinimumExact( word t, int * pComp, int * pPerm )
{
word tMin = ~(word)0;
word tCur, tTemp1, tTemp2;
......@@ -2312,6 +2312,87 @@ word Extra_Truth6Minimum( word t, int * pComp, int * pPerm )
/**Function*************************************************************
Synopsis [Perform heuristic TT minimization.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Extra_Truth6Ones( word t )
{
t = (t & 0x5555555555555555) + ((t>> 1) & 0x5555555555555555);
t = (t & 0x3333333333333333) + ((t>> 2) & 0x3333333333333333);
t = (t & 0x0F0F0F0F0F0F0F0F) + ((t>> 4) & 0x0F0F0F0F0F0F0F0F);
t = (t & 0x00FF00FF00FF00FF) + ((t>> 8) & 0x00FF00FF00FF00FF);
t = (t & 0x0000FFFF0000FFFF) + ((t>>16) & 0x0000FFFF0000FFFF);
return (t & 0x00000000FFFFFFFF) + (t>>32);
}
static inline word Extra_Truth6MinimumRoundOne( word t, int v )
{
word tCur, tMin = t; // ab
assert( v >= 0 && v < 5 );
tCur = Extra_Truth6ChangePhase( t, v ); // !ab
tMin = Abc_MinWord( tMin, tCur );
tCur = Extra_Truth6ChangePhase( t, v+1 ); // a!b
tMin = Abc_MinWord( tMin, tCur );
tCur = Extra_Truth6ChangePhase( tCur, v ); // !a!b
tMin = Abc_MinWord( tMin, tCur );
t = Extra_Truth6SwapAdjacent( t, v ); // ba
tMin = Abc_MinWord( tMin, t );
tCur = Extra_Truth6ChangePhase( t, v ); // !ba
tMin = Abc_MinWord( tMin, tCur );
tCur = Extra_Truth6ChangePhase( t, v+1 ); // b!a
tMin = Abc_MinWord( tMin, tCur );
tCur = Extra_Truth6ChangePhase( tCur, v ); // !b!a
tMin = Abc_MinWord( tMin, tCur );
return tMin;
}
static inline word Extra_Truth6MinimumRoundMany( word t )
{
int i, k, Limit = 10;
word tCur, tMin = t;
for ( i = 0; i < Limit; i++ )
{
word tMin0 = tMin;
for ( k = 4; k >= 0; k-- )
{
tCur = Extra_Truth6MinimumRoundOne( tMin, k );
tMin = Abc_MinWord( tMin, tCur );
}
if ( tMin0 == tMin )
break;
}
return tMin;
}
word Extra_Truth6MinimumHeuristic( word t )
{
word tMin1, tMin2;
int nOnes = Extra_Truth6Ones( t );
if ( nOnes < 32 )
return Extra_Truth6MinimumRoundMany( t );
if ( nOnes > 32 )
return Extra_Truth6MinimumRoundMany( ~t );
tMin1 = Extra_Truth6MinimumRoundMany( t );
tMin2 = Extra_Truth6MinimumRoundMany( ~t );
return Abc_MinWord( tMin1, tMin2 );
}
void Extra_Truth6MinimumHeuristicTest()
{
word t = 0x5555555555555555 & ~(0x3333333333333333 & 0x0F0F0F0F0F0F0F0F);
Extra_Truth6MinimumRoundMany( t );
t = 0;
}
/**Function*************************************************************
Synopsis [Reads functions from file.]
Description []
......@@ -2387,7 +2468,7 @@ void Extra_NpnTest2()
word tMin, t = 0xa2222aaa08888000;
pComp = Extra_GreyCodeSchedule( 6 );
pPerm = Extra_PermSchedule( 6 );
tMin = Extra_Truth6Minimum( t, pComp, pPerm );
tMin = Extra_Truth6MinimumExact( t, pComp, pPerm );
ABC_FREE( pPerm );
ABC_FREE( pComp );
......@@ -2424,7 +2505,7 @@ void Extra_NpnTest()
// compute minimum forms
for ( i = 0; i < nFuncs; i++ )
{
pFuncs[i] = Extra_Truth6Minimum( pFuncs[i], pComp, pPerm );
pFuncs[i] = Extra_Truth6MinimumExact( pFuncs[i], pComp, pPerm );
if ( i % 10000 == 0 )
printf( "%d\n", i );
}
......
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