mirror of https://github.com/YosysHQ/abc.git
Exploration of functions.
This commit is contained in:
parent
fd1ed5b232
commit
5acb147f61
|
|
@ -10320,8 +10320,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||||
int nCutMax = 1;
|
int nCutMax = 1;
|
||||||
int nLeafMax = 10;
|
int nLeafMax = 10;
|
||||||
int nDivMax = 50;
|
int nDivMax = 2;
|
||||||
int nDecMax = 20;
|
int nDecMax = 3;
|
||||||
int fNewAlgo = 0;
|
int fNewAlgo = 0;
|
||||||
int fNewOrder = 0;
|
int fNewOrder = 0;
|
||||||
int fVerbose = 0;
|
int fVerbose = 0;
|
||||||
|
|
@ -10461,8 +10461,8 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
extern void Abc_EnumerateFunctions( int nVars );
|
extern void Abc_EnumerateFuncs( int nDecMax, int nDivMax, int fVerbose );
|
||||||
Abc_EnumerateFunctions( nDecMax );
|
Abc_EnumerateFuncs( nDecMax, nDivMax, fVerbose );
|
||||||
}
|
}
|
||||||
if ( pNtk )
|
if ( pNtk )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "misc/vec/vec.h"
|
#include "misc/vec/vec.h"
|
||||||
#include "misc/vec/vecHsh.h"
|
#include "misc/vec/vecHsh.h"
|
||||||
|
#include "bool/kit/kit.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_START
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
|
@ -414,6 +415,209 @@ void Abc_EnumerateFunctions( int nDecMax )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis []
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
#define ABC_ENUM_MAX 32
|
||||||
|
static word s_Truths6[6] = {
|
||||||
|
ABC_CONST(0xAAAAAAAAAAAAAAAA),
|
||||||
|
ABC_CONST(0xCCCCCCCCCCCCCCCC),
|
||||||
|
ABC_CONST(0xF0F0F0F0F0F0F0F0),
|
||||||
|
ABC_CONST(0xFF00FF00FF00FF00),
|
||||||
|
ABC_CONST(0xFFFF0000FFFF0000),
|
||||||
|
ABC_CONST(0xFFFFFFFF00000000)
|
||||||
|
};
|
||||||
|
typedef struct Abc_EnuMan_t_ Abc_EnuMan_t;
|
||||||
|
struct Abc_EnuMan_t_
|
||||||
|
{
|
||||||
|
int nVars; // support size
|
||||||
|
int nVarsFree; // number of PIs used
|
||||||
|
int fVerbose; // verbose flag
|
||||||
|
int nNodeMax; // the max number of nodes
|
||||||
|
int nNodes; // current number of gates
|
||||||
|
int nTops; // the number of fanoutless gates
|
||||||
|
int pFans0[ABC_ENUM_MAX]; // fanins
|
||||||
|
int pFans1[ABC_ENUM_MAX]; // fanins
|
||||||
|
int fCompl0[ABC_ENUM_MAX]; // complements
|
||||||
|
int fCompl1[ABC_ENUM_MAX]; // complements
|
||||||
|
int pRefs[ABC_ENUM_MAX]; // references
|
||||||
|
word pTruths[ABC_ENUM_MAX]; // truth tables
|
||||||
|
word nTries; // attempts to build a gate
|
||||||
|
word nBuilds; // actually built gates
|
||||||
|
word nFinished; // finished structures
|
||||||
|
};
|
||||||
|
static inline void Abc_EnumRef( Abc_EnuMan_t * p, int i )
|
||||||
|
{
|
||||||
|
assert( p->pRefs[i] >= 0 );
|
||||||
|
if ( p->pRefs[i]++ == 0 )
|
||||||
|
p->nTops--;
|
||||||
|
}
|
||||||
|
static inline void Abc_EnumDeref( Abc_EnuMan_t * p, int i )
|
||||||
|
{
|
||||||
|
if ( --p->pRefs[i] == 0 )
|
||||||
|
p->nTops++;
|
||||||
|
assert( p->pRefs[i] >= 0 );
|
||||||
|
}
|
||||||
|
static inline void Abc_EnumRefNode( Abc_EnuMan_t * p, int i )
|
||||||
|
{
|
||||||
|
Abc_EnumRef( p, p->pFans0[i] );
|
||||||
|
Abc_EnumRef( p, p->pFans1[i] );
|
||||||
|
p->nTops++;
|
||||||
|
p->nNodes++;
|
||||||
|
assert( i < p->nNodes );
|
||||||
|
}
|
||||||
|
static inline void Abc_EnumDerefNode( Abc_EnuMan_t * p, int i )
|
||||||
|
{
|
||||||
|
assert( i < p->nNodes );
|
||||||
|
Abc_EnumDeref( p, p->pFans0[i] );
|
||||||
|
Abc_EnumDeref( p, p->pFans1[i] );
|
||||||
|
p->nTops--;
|
||||||
|
p->nNodes--;
|
||||||
|
}
|
||||||
|
static inline void Abc_EnumPrintOne( Abc_EnuMan_t * p )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Kit_DsdPrintFromTruth( (unsigned *)(p->pTruths + p->nNodes - 1), p->nVars );
|
||||||
|
for ( i = p->nVars; i < p->nNodes; i++ )
|
||||||
|
printf( " %c=%s%c%s%c", 'a'+i, p->fCompl0[i]?"!":"", 'a'+p->pFans0[i], p->fCompl1[i]?"!":"", 'a'+p->pFans1[i] );
|
||||||
|
printf( "\n" );
|
||||||
|
}
|
||||||
|
void Abc_EnumerateFuncs_rec( Abc_EnuMan_t * p )
|
||||||
|
{
|
||||||
|
word uTruth, uTemp;
|
||||||
|
word * pTruth = p->pTruths;
|
||||||
|
int f = p->nVarsFree;
|
||||||
|
int n = p->nNodes;
|
||||||
|
int i, k, c0, c1, t, a, b;
|
||||||
|
p->nBuilds++;
|
||||||
|
// terminate when enough and no new tops
|
||||||
|
if ( n == p->nNodeMax && p->nTops == 1 )
|
||||||
|
{
|
||||||
|
if ( p->fVerbose )
|
||||||
|
Abc_EnumPrintOne( p );
|
||||||
|
p->nFinished++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( p->nTops > p->nNodeMax - n + 1 )
|
||||||
|
return;
|
||||||
|
assert( n < p->nNodeMax );
|
||||||
|
// try new gates with two inputs
|
||||||
|
if ( f >= 2 )
|
||||||
|
{
|
||||||
|
p->pFans0[n] = f - 2;
|
||||||
|
p->pFans1[n] = f - 1;
|
||||||
|
p->fCompl0[n] = 0;
|
||||||
|
p->fCompl1[n] = 0;
|
||||||
|
p->pTruths[n] = pTruth[f - 2] & pTruth[f - 1];
|
||||||
|
p->nVarsFree -= 2;
|
||||||
|
Abc_EnumRefNode( p, n );
|
||||||
|
Abc_EnumerateFuncs_rec( p );
|
||||||
|
Abc_EnumDerefNode( p, n );
|
||||||
|
p->nVarsFree += 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// try new gates with one input
|
||||||
|
if ( f > 0 )
|
||||||
|
{
|
||||||
|
for ( i = f; i < n; i++ )
|
||||||
|
for ( c0 = 0; c0 < 2; c0++ )
|
||||||
|
{
|
||||||
|
uTruth = pTruth[f - 1] & (c0 ? ~pTruth[i] : pTruth[i]);
|
||||||
|
p->pFans0[n] = f - 1;
|
||||||
|
p->pFans1[n] = i;
|
||||||
|
p->fCompl0[n] = 0;
|
||||||
|
p->fCompl1[n] = c0;
|
||||||
|
p->pTruths[n] = uTruth;
|
||||||
|
p->nVarsFree--;
|
||||||
|
Abc_EnumRefNode( p, n );
|
||||||
|
Abc_EnumerateFuncs_rec( p );
|
||||||
|
Abc_EnumDerefNode( p, n );
|
||||||
|
p->nVarsFree++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// try new gates without inputs
|
||||||
|
for ( i = f; i < n; i++ )
|
||||||
|
for ( k = i+1; k < n; k++ )
|
||||||
|
for ( c0 = 0; c0 < 2; c0++ )
|
||||||
|
for ( c1 = 0; c1 < 2; c1++ )
|
||||||
|
{
|
||||||
|
uTruth = (c0 ? ~pTruth[i] : pTruth[i]) & (c1 ? ~pTruth[k] : pTruth[k]);
|
||||||
|
if ( uTruth == 0 || ~uTruth == 0 )
|
||||||
|
continue;
|
||||||
|
for ( t = f; t < n; t++ )
|
||||||
|
if ( uTruth == p->pTruths[t] || ~uTruth == p->pTruths[t] )
|
||||||
|
break;
|
||||||
|
if ( t < n )
|
||||||
|
continue;
|
||||||
|
for ( a = f; a <= i; a++ )
|
||||||
|
{
|
||||||
|
for ( b = a + 1; b <= k; b++ )
|
||||||
|
{
|
||||||
|
if ( a == i && b == k )
|
||||||
|
continue;
|
||||||
|
uTemp = p->pTruths[a] & p->pTruths[b];
|
||||||
|
if ( uTruth == uTemp || ~uTruth == uTemp )
|
||||||
|
break;
|
||||||
|
uTemp = p->pTruths[a] & ~p->pTruths[b];
|
||||||
|
if ( uTruth == uTemp || ~uTruth == uTemp )
|
||||||
|
break;
|
||||||
|
uTemp = ~p->pTruths[a] & p->pTruths[b];
|
||||||
|
if ( uTruth == uTemp || ~uTruth == uTemp )
|
||||||
|
break;
|
||||||
|
uTemp = ~p->pTruths[a] & ~p->pTruths[b];
|
||||||
|
if ( uTruth == uTemp || ~uTruth == uTemp )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( b <= k )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( a <= i )
|
||||||
|
continue;
|
||||||
|
p->pFans0[n] = i;
|
||||||
|
p->pFans1[n] = k;
|
||||||
|
p->fCompl0[n] = c0;
|
||||||
|
p->fCompl1[n] = c1;
|
||||||
|
p->pTruths[n] = uTruth;
|
||||||
|
Abc_EnumRefNode( p, n );
|
||||||
|
Abc_EnumerateFuncs_rec( p );
|
||||||
|
Abc_EnumDerefNode( p, n );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Abc_EnumerateFuncs( int nVars, int nGates, int fVerbose )
|
||||||
|
{
|
||||||
|
abctime clk = Abc_Clock();
|
||||||
|
Abc_EnuMan_t P, * p = &P; int i;
|
||||||
|
if ( nVars > nGates + 1 )
|
||||||
|
{
|
||||||
|
printf( "The gate count %d is not enough to have functions with %d inputs.\n", nGates, nVars );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert( nVars >= 3 && nVars <= 6 );
|
||||||
|
assert( nGates > 0 && nVars + nGates < 16 );
|
||||||
|
memset( p, 0, sizeof(Abc_EnuMan_t) );
|
||||||
|
p->fVerbose = fVerbose;
|
||||||
|
p->nVars = nVars;
|
||||||
|
p->nVarsFree = nVars;
|
||||||
|
p->nNodeMax = nVars + nGates;
|
||||||
|
p->nNodes = nVars;
|
||||||
|
p->nTops = nVars;
|
||||||
|
for ( i = 0; i < nVars; i++ )
|
||||||
|
p->pTruths[i] = s_Truths6[i];
|
||||||
|
Abc_EnumerateFuncs_rec( p );
|
||||||
|
printf( "Vars = %d. Gates = %d. Tries = %u. Builds = %u. Finished = %d. ",
|
||||||
|
nVars, nGates, (unsigned)p->nTries, (unsigned)p->nBuilds, (unsigned)p->nFinished );
|
||||||
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue