mirror of https://github.com/YosysHQ/abc.git
Group based exact NPN classification.
This commit is contained in:
parent
a309569390
commit
6842b8cdbc
|
|
@ -293,17 +293,18 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
|
|||
}
|
||||
else if ( NpnType == 7 )
|
||||
{
|
||||
extern unsigned Abc_TtCanonicizeHie( Abc_TtMan_t * p, word * pTruth, int nVars, char * pCanonPerm );
|
||||
extern unsigned Abc_TtCanonicizeHie( Abc_TtMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int fExact );
|
||||
extern Abc_TtMan_t * Abc_TtManStart( int nVars );
|
||||
extern void Abc_TtManStop( Abc_TtMan_t * p );
|
||||
extern int Abc_TtManNumClasses( Abc_TtMan_t * p );
|
||||
|
||||
int fExact = 0;
|
||||
Abc_TtMan_t * pMan = Abc_TtManStart( p->nVars );
|
||||
for ( i = 0; i < p->nFuncs; i++ )
|
||||
{
|
||||
if ( fVerbose )
|
||||
printf( "%7d : ", i );
|
||||
uCanonPhase = Abc_TtCanonicizeHie( pMan, p->pFuncs[i], p->nVars, pCanonPerm );
|
||||
uCanonPhase = Abc_TtCanonicizeHie( pMan, p->pFuncs[i], p->nVars, pCanonPerm, fExact );
|
||||
if ( fVerbose )
|
||||
// Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(NULL, uCanonPhase, p->nVars), printf( "\n" );
|
||||
printf( "\n" );
|
||||
|
|
|
|||
|
|
@ -148,6 +148,11 @@ static inline void minWord3(word* a, word* b, word* minimal, int nVars)
|
|||
if (memCompare(b, minimal, nVars) <= 0)
|
||||
Kit_TruthCopy_64bit( minimal, b, nVars );
|
||||
}
|
||||
static inline void minWord1(word* a, word* minimal, int nVars)
|
||||
{
|
||||
if (memCompare(a, minimal, nVars) <= 0)
|
||||
Kit_TruthCopy_64bit( minimal, a, nVars );
|
||||
}
|
||||
void simpleMinimal(word* x, word* pAux,word* minimal, permInfo* pi, int nVars)
|
||||
{
|
||||
int i,j=0;
|
||||
|
|
@ -179,5 +184,119 @@ void simpleMinimal(word* x, word* pAux,word* minimal, permInfo* pi, int nVars)
|
|||
Kit_TruthCopy_64bit( x, minimal, nVars );
|
||||
}
|
||||
|
||||
/**
|
||||
* pGroups: we assume that the variables are merged into adjacent groups,
|
||||
* the size of each group is stored in pGroups
|
||||
* nGroups: the number of groups
|
||||
*
|
||||
* pis: we compute all permInfos from 0 to nVars (incl.)
|
||||
*/
|
||||
void simpleMinimalGroups(word* x, word* pAux, word* minimal, int* pGroups, int nGroups, permInfo** pis, int nVars, int fFlipOutput, int fFlipInput)
|
||||
{
|
||||
/* variables */
|
||||
int i, j, o, nn;
|
||||
permInfo* pi;
|
||||
|
||||
/* reorder groups and calculate group offsets */
|
||||
int offset[nGroups];
|
||||
o = 0;
|
||||
j = 0;
|
||||
|
||||
for ( i = 0; i < nGroups; ++i )
|
||||
{
|
||||
offset[j] = o;
|
||||
o += pGroups[j];
|
||||
++j;
|
||||
}
|
||||
|
||||
if ( fFlipOutput )
|
||||
{
|
||||
/* keep regular and inverted version of x */
|
||||
Kit_TruthCopy_64bit( pAux, x, nVars );
|
||||
Kit_TruthNot_64bit( x, nVars );
|
||||
|
||||
minWord(x, pAux, minimal, nVars);
|
||||
}
|
||||
else
|
||||
{
|
||||
Kit_TruthCopy_64bit( minimal, x, nVars );
|
||||
}
|
||||
|
||||
/* iterate through all combinations of pGroups using mixed radix enumeration */
|
||||
nn = ( nGroups << 1 ) + 1;
|
||||
int a[nn];
|
||||
int c[nn];
|
||||
int m[nn];
|
||||
|
||||
/* fill a and m arrays */
|
||||
m[0] = 2;
|
||||
for ( i = 1; i <= nGroups; ++i ) { m[i] = pis[pGroups[i - 1]]->totalFlips + 1; }
|
||||
for ( i = 1; i <= nGroups; ++i ) { m[nGroups + i] = pis[pGroups[i - 1]]->totalSwaps + 1; }
|
||||
for ( i = 0; i < nn; ++i ) { a[i] = c[i] = 0; }
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
/* consider all flips */
|
||||
for ( i = 1; i <= nGroups; ++i )
|
||||
{
|
||||
if ( !c[i] ) { continue; }
|
||||
if ( !fFlipInput && pGroups[i - 1] == 1 ) { continue; }
|
||||
|
||||
pi = pis[pGroups[i - 1]];
|
||||
j = a[i] == 0 ? 0 : pi->totalFlips - a[i];
|
||||
|
||||
Kit_TruthChangePhase_64bit(x, nVars, offset[i - 1] + pi->flipArray[j]);
|
||||
if ( fFlipOutput )
|
||||
{
|
||||
Kit_TruthChangePhase_64bit(pAux, nVars, offset[i - 1] + pi->flipArray[j]);
|
||||
minWord3(x, pAux, minimal, nVars);
|
||||
}
|
||||
else
|
||||
{
|
||||
minWord1(x, minimal, nVars);
|
||||
}
|
||||
}
|
||||
|
||||
/* consider all swaps */
|
||||
for ( i = 1; i <= nGroups; ++i )
|
||||
{
|
||||
if ( !c[nGroups + i] ) { continue; }
|
||||
if ( pGroups[i - 1] == 1 ) { continue; }
|
||||
|
||||
pi = pis[pGroups[i - 1]];
|
||||
if ( a[nGroups + i] == pi->totalSwaps )
|
||||
{
|
||||
j = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
j = pi->swapArray[pi->totalSwaps - a[nGroups + i] - 1];
|
||||
}
|
||||
Kit_TruthSwapAdjacentVars_64bit(x, nVars, offset[i - 1] + j);
|
||||
if ( fFlipOutput )
|
||||
{
|
||||
Kit_TruthSwapAdjacentVars_64bit(pAux, nVars, offset[i - 1] + j);
|
||||
minWord3(x, pAux, minimal, nVars);
|
||||
}
|
||||
else
|
||||
{
|
||||
minWord1(x, minimal, nVars);
|
||||
}
|
||||
}
|
||||
|
||||
/* update a's */
|
||||
memset(c, 0, sizeof(int) * nn);
|
||||
j = nn - 1;
|
||||
while ( a[j] == m[j] - 1 ) { c[j] = 1; a[j--] = 0; }
|
||||
|
||||
/* done? */
|
||||
if ( j == 0 ) { break; }
|
||||
|
||||
c[j] = 1;
|
||||
a[j]++;
|
||||
}
|
||||
|
||||
Kit_TruthCopy_64bit( x, minimal, nVars );
|
||||
}
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "dauInt.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
#include "misc/vec/vecMem.h"
|
||||
#include "bool/lucky/lucky.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -1053,7 +1054,7 @@ unsigned Abc_TtCanonicizePhase( word * pTruth, int nVars )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
#define TT_NUM_TABLES 4
|
||||
#define TT_NUM_TABLES 5
|
||||
|
||||
struct Abc_TtMan_t_
|
||||
{
|
||||
|
|
@ -1086,7 +1087,7 @@ int Abc_TtManNumClasses( Abc_TtMan_t * p )
|
|||
return Vec_MemEntryNum( p->vTtMem[TT_NUM_TABLES-1] );
|
||||
}
|
||||
|
||||
unsigned Abc_TtCanonicizeHie( Abc_TtMan_t * p, word * pTruthInit, int nVars, char * pCanonPerm )
|
||||
unsigned Abc_TtCanonicizeHie( Abc_TtMan_t * p, word * pTruthInit, int nVars, char * pCanonPerm, int fExact )
|
||||
{
|
||||
int fNaive = 1;
|
||||
int pStore[17];
|
||||
|
|
@ -1181,6 +1182,52 @@ unsigned Abc_TtCanonicizeHie( Abc_TtMan_t * p, word * pTruthInit, int nVars, cha
|
|||
if ( *pSpot != -1 )
|
||||
return 0;
|
||||
truthId = Vec_MemHashInsert( p->vTtMem[3], pTruth );
|
||||
|
||||
// perform exact NPN using groups
|
||||
if ( fExact ) {
|
||||
extern void simpleMinimalGroups(word* x, word* pAux, word* minimal, int* pGroups, int nGroups, permInfo** pis, int nVars, int fFlipOutput, int fFlipInput);
|
||||
word pAuxWord[1024], pAuxWord1[1024];
|
||||
int pGroups[nVars];
|
||||
int nGroups = 0;
|
||||
// get groups
|
||||
pGroups[0] = 0;
|
||||
for (i = 0; i < nVars - 1; i++) {
|
||||
if (pStore[i] == pStore[i + 1]) {
|
||||
pGroups[nGroups]++;
|
||||
} else {
|
||||
pGroups[nGroups]++;
|
||||
nGroups++;
|
||||
pGroups[nGroups] = 0;
|
||||
}
|
||||
}
|
||||
pGroups[nGroups]++;
|
||||
nGroups++;
|
||||
|
||||
// compute permInfo from 0 to nVars (incl.)
|
||||
permInfo * pis[nVars+1];
|
||||
for (i = 0; i <= nVars; i++) {
|
||||
pis[i] = setPermInfoPtr(i);
|
||||
}
|
||||
|
||||
// do the exact matching
|
||||
if (nOnes == nWords * 32) /* balanced output */
|
||||
simpleMinimalGroups(pTruth, pAuxWord, pAuxWord1, pGroups, nGroups, pis, nVars, 1, 1);
|
||||
else if (pStore[0] != pStore[1] && pStore[0] == (nOnes - pStore[0])) /* balanced singleton input */
|
||||
simpleMinimalGroups(pTruth, pAuxWord, pAuxWord1, pGroups, nGroups, pis, nVars, 0, 1);
|
||||
else
|
||||
simpleMinimalGroups(pTruth, pAuxWord, pAuxWord1, pGroups, nGroups, pis, nVars, 0, 0);
|
||||
|
||||
// cleanup
|
||||
for (i = 0; i <= nVars; i++) {
|
||||
freePermInfoPtr(pis[i]);
|
||||
}
|
||||
}
|
||||
// check cache
|
||||
pSpot = Vec_MemHashLookup( p->vTtMem[4], pTruth );
|
||||
if ( *pSpot != -1 )
|
||||
return 0;
|
||||
truthId = Vec_MemHashInsert( p->vTtMem[4], pTruth );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue