mirror of https://github.com/YosysHQ/abc.git
LUT cascade mapping.
This commit is contained in:
parent
45c250fb5b
commit
75ef06017d
|
|
@ -8853,7 +8853,7 @@ int Abc_CommandCascade( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Empty network.\n" );
|
||||
Abc_Print( -1, "Empty neAtwork.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -8910,12 +8910,12 @@ usage:
|
|||
***********************************************************************/
|
||||
int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_NtkLutCascade2( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose );
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pNtkRes;
|
||||
int c, nLutSize = 6, nLuts = 8, nRails = 1, nIters = 1, fVerbose = 0;
|
||||
extern Abc_Ntk_t * Abc_NtkLutCascadeGen( int nLutSize, int nStages, int nRails, int nShared, int fVerbose );
|
||||
extern Abc_Ntk_t * Abc_NtkLutCascade2( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose, char * pGuide );
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pNtkRes; char * pGuide = NULL;
|
||||
int c, nLutSize = 6, nStages = 8, nRails = 1, nShared = 2, nIters = 1, fGen = 0, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KNRIvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KMRSIgvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -8930,15 +8930,15 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nLutSize < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'N':
|
||||
case 'M':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||
Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nLuts = atoi(argv[globalUtilOptind]);
|
||||
nStages = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nLuts < 0 )
|
||||
if ( nStages < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'R':
|
||||
|
|
@ -8952,6 +8952,17 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nRails < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'S':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nShared = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nShared < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'I':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
|
|
@ -8963,6 +8974,9 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nIters < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'g':
|
||||
fGen ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -8972,6 +8986,17 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( fGen )
|
||||
{
|
||||
pNtkRes = Abc_NtkLutCascadeGen( nLutSize, nStages, nRails, nShared, fVerbose );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
Abc_Print( -1, "LUT cascade generation failed.\n" );
|
||||
return 1;
|
||||
}
|
||||
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( pNtk == NULL )
|
||||
{
|
||||
|
|
@ -8988,13 +9013,15 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "Run command \"strash\" to convert the network into an AIG.\n" );
|
||||
return 1;
|
||||
}
|
||||
if ( Abc_NtkCiNum(pNtk) > nLutSize + (nLutSize - nRails) * (nLuts - 1) )
|
||||
if ( Abc_NtkCiNum(pNtk) > nLutSize + (nLutSize - nRails) * (nStages - 1) )
|
||||
{
|
||||
Abc_Print( -1, "Cannot decompose %d-input function into a %d-rail cascade of %d %d-LUTs (max suppose size = %d).\n",
|
||||
Abc_NtkCiNum(pNtk), nRails, nLuts, nLutSize, nLutSize + (nLutSize - nRails) * (nLuts - 1) );
|
||||
Abc_NtkCiNum(pNtk), nRails, nStages, nLutSize, nLutSize + (nLutSize - nRails) * (nStages - 1) );
|
||||
return 1;
|
||||
}
|
||||
pNtkRes = Abc_NtkLutCascade2( pNtk, nLutSize, nLuts, nRails, nIters, fVerbose );
|
||||
if ( argc == globalUtilOptind + 1 )
|
||||
pGuide = argv[globalUtilOptind];
|
||||
pNtkRes = Abc_NtkLutCascade2( pNtk, nLutSize, nStages, nRails, nIters, fVerbose, pGuide );
|
||||
if ( pNtkRes == NULL )
|
||||
{
|
||||
Abc_Print( -1, "LUT cascade mapping failed.\n" );
|
||||
|
|
@ -9004,12 +9031,14 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: lutcasdec [-KNRI <num>] [-vh]\n" );
|
||||
Abc_Print( -2, "usage: lutcasdec [-KMRSI <num>] [-vh]\n" );
|
||||
Abc_Print( -2, "\t decomposes the primary output functions into LUT cascades\n" );
|
||||
Abc_Print( -2, "\t-K <num> : the number of LUT inputs [default = %d]\n", nLutSize );
|
||||
Abc_Print( -2, "\t-N <num> : the number of LUTs in the cascade [default = %d]\n", nLuts );
|
||||
Abc_Print( -2, "\t-M <num> : the maximum delay (the number of stages) [default = %d]\n", nStages );
|
||||
Abc_Print( -2, "\t-R <num> : the number of direct connections (rails) [default = %d]\n", nRails );
|
||||
Abc_Print( -2, "\t-S <num> : the number of shared variables in each stage [default = %d]\n", nShared );
|
||||
Abc_Print( -2, "\t-I <num> : the number of iterations when looking for a solution [default = %d]\n", nIters );
|
||||
Abc_Print( -2, "\t-g : toggle generating random cascade with these parameters [default = %s]\n", fGen? "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");
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@
|
|||
#include "base/abc/abc.h"
|
||||
#include "bool/kit/kit.h"
|
||||
#include "aig/miniaig/miniaig.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
#ifdef ABC_USE_CUDD
|
||||
#include "bdd/extrab/extraBdd.h"
|
||||
#include "bdd/extrab/extraLutCas.h"
|
||||
//#include "bdd/extrab/extraLutCas.h"
|
||||
#endif
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
|
@ -131,7 +132,7 @@ word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int nLuts, int nRails, int
|
|||
- the number of words in this block
|
||||
- the number of fanins
|
||||
- the list of fanins
|
||||
- the variable ID of the output (can be one of the fanin variables)
|
||||
- the variable ID of the output (should be a LUT counter starting with the number of variables)
|
||||
- truth tables (one word for 6 vars or less; more words as needed for more than 6 vars)
|
||||
For a 6-input node, the LUT info block takes 10 words (block size, fanin count, 6 fanins, output ID, truth table).
|
||||
For a 4-input node, the LUT info block takes 8 words (block size, fanin count, 4 fanins, output ID, truth table).
|
||||
|
|
@ -159,37 +160,157 @@ word * Abc_LutCascadeGenTest()
|
|||
pLuts[1+1] = 6;
|
||||
for ( i = 0; i < 6; i++ )
|
||||
pLuts[1+2+i] = i;
|
||||
pLuts[1+8] = 0;
|
||||
pLuts[1+8] = 9;
|
||||
pLuts[1+9] = ABC_CONST(0x8000000000000000);
|
||||
// second node
|
||||
pLuts[11+0] = 8;
|
||||
pLuts[11+1] = 4;
|
||||
for ( i = 0; i < 4; i++ )
|
||||
pLuts[11+2+i] = i ? i + 5 : 0;
|
||||
pLuts[11+6] = 1;
|
||||
pLuts[11+2+i] = i ? i + 5 : 9;
|
||||
pLuts[11+6] = 10;
|
||||
pLuts[11+7] = ABC_CONST(0xFFFEFFFEFFFEFFFE);
|
||||
return pLuts;
|
||||
}
|
||||
void Abc_LutCascadePrintLut( word * pLuts, int n, int i )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
printf( "LUT%d : ", n );
|
||||
printf( "%c = F( ", 'a'+(int)pIns[nIns] );
|
||||
for ( int k = 0; k < nIns; k++ )
|
||||
printf( "%c ", 'a'+(int)pIns[k] );
|
||||
printf( ") " );
|
||||
Abc_TtPrintHexRev( stdout, pT, nIns );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Abc_LutCascadePrint( word * pLuts )
|
||||
{
|
||||
int n, i, k;
|
||||
printf( "Single-rail LUT cascade has %d nodes:\n", (int)pLuts[0] );
|
||||
int n, i;
|
||||
printf( "The LUT cascade contains %d LUTs:\n", (int)pLuts[0] );
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
Abc_LutCascadePrintLut( pLuts, n, i );
|
||||
}
|
||||
void Abc_LutCascadeGenOne( Vec_Wrd_t * vRes, int nIns, int * pIns, int Out, word * p )
|
||||
{
|
||||
int w, nWords = Abc_TtWordNum(nIns);
|
||||
//int iStart = Vec_WrdSize(vRes);
|
||||
Vec_WrdAddToEntry(vRes, 0, 1);
|
||||
Vec_WrdPush( vRes, 3+nIns+nWords );
|
||||
Vec_WrdPush( vRes, nIns );
|
||||
for ( w = 0; w < nIns; w++ )
|
||||
Vec_WrdPush( vRes, pIns[w] );
|
||||
Vec_WrdPush( vRes, Out );
|
||||
if ( nIns < 6 )
|
||||
Vec_WrdPush( vRes, p ? p[0] : Abc_Tt6Stretch(Abc_Random(0), nIns) );
|
||||
else
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
Vec_WrdPush( vRes, p ? p[w] : Abc_RandomW(0) );
|
||||
//printf("Adding LUT: "); Abc_LutCascadePrintLut( Vec_WrdArray(vRes), 0, iStart );
|
||||
}
|
||||
word * Abc_LutCascadeGen( int nVars, int nLutSize, int nRails, int nShared )
|
||||
{
|
||||
assert( nLutSize - nRails - nShared > 0 );
|
||||
Vec_Wrd_t * vRes = Vec_WrdStart( 1 );
|
||||
Vec_Int_t * vFanins = Vec_IntAlloc( nLutSize );
|
||||
Vec_Int_t * vVars = Vec_IntStartNatural( nVars );
|
||||
Vec_Str_t * vGuide = Vec_StrAlloc( 100 );
|
||||
Abc_Random(1);
|
||||
int i, c = 0, Obj, iVarNext = nVars, iVarPrev = -1;
|
||||
while ( Vec_IntSize(vVars) > nLutSize ) {
|
||||
if ( Vec_WrdSize(vRes) > 1 )
|
||||
for ( i = 0; i < nRails; i++ )
|
||||
Vec_IntPop( vVars );
|
||||
Vec_StrPush( vGuide, '0'+c++ );
|
||||
Vec_IntClear( vFanins );
|
||||
for ( i = 0; i < nShared; i++ ) {
|
||||
int Index = -1;
|
||||
do Index = Abc_Random(0) % Vec_IntSize(vVars);
|
||||
while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
|
||||
Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
|
||||
Vec_StrPush( vGuide, 'A'+Vec_IntEntry(vVars, Index) );
|
||||
}
|
||||
for ( i = 0; i < nLutSize - nRails - nShared; i++ ) {
|
||||
int Index = -1;
|
||||
do Index = Abc_Random(0) % Vec_IntSize(vVars);
|
||||
while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
|
||||
Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
|
||||
Vec_StrPush( vGuide, 'a'+Vec_IntEntry(vVars, Index) );
|
||||
Vec_IntDrop( vVars, Index );
|
||||
}
|
||||
if ( Vec_WrdSize(vRes) == 1 ) {
|
||||
for ( i = 0; i < nRails; i++ ) {
|
||||
int Index = -1;
|
||||
do Index = Abc_Random(0) % Vec_IntSize(vVars);
|
||||
while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
|
||||
Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
|
||||
Vec_StrPush( vGuide, 'a'+Vec_IntEntry(vVars, Index) );
|
||||
Vec_IntDrop( vVars, Index );
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert( iVarPrev > 0 );
|
||||
for ( i = 0; i < nRails; i++ ) {
|
||||
Vec_IntPush( vFanins, iVarPrev+i );
|
||||
Vec_StrPush( vGuide, 'a'+iVarPrev+i );
|
||||
}
|
||||
}
|
||||
iVarPrev = iVarNext;
|
||||
assert( Vec_IntSize(vFanins) == nLutSize );
|
||||
for ( i = 0; i < nRails; i++ ) {
|
||||
Abc_LutCascadeGenOne( vRes, Vec_IntSize(vFanins), Vec_IntArray(vFanins), iVarNext++, NULL );
|
||||
Vec_IntPush( vVars, iVarPrev+i );
|
||||
}
|
||||
}
|
||||
assert( Vec_IntSize(vVars) <= nLutSize );
|
||||
Abc_LutCascadeGenOne( vRes, Vec_IntSize(vVars), Vec_IntArray(vVars), iVarNext, NULL );
|
||||
Vec_StrPush( vGuide, '0'+c++ );
|
||||
Vec_IntForEachEntry( vVars, Obj, i )
|
||||
Vec_StrPush( vGuide, 'a'+Obj );
|
||||
Vec_StrPush( vGuide, '\0' );
|
||||
|
||||
printf( "Generated %d-LUT cascade for a %d-var function with %d rails and %d shared vars (node = %d, level = %d).\n",
|
||||
nLutSize, nVars, nRails, nShared, (int)Vec_WrdEntry(vRes, 0), c );
|
||||
printf( "Structural info: %s\n", Vec_StrArray(vGuide) );
|
||||
Vec_StrFree( vGuide );
|
||||
|
||||
word * pRes = Vec_WrdReleaseArray(vRes);
|
||||
Vec_WrdFree( vRes );
|
||||
return pRes;
|
||||
}
|
||||
word * Abc_LutCascadeTruth( word * pLuts, int nVars )
|
||||
{
|
||||
int nWords = Abc_TtWordNum(nVars);
|
||||
Vec_Wrd_t * vFuncs = Vec_WrdStartTruthTables6( nVars );
|
||||
Vec_WrdFillExtra( vFuncs, nWords*(nVars+pLuts[0]+1), (word)0 );
|
||||
word * pCube = Vec_WrdEntryP( vFuncs, nWords*(nVars+pLuts[0]) );
|
||||
int n, i, m, v, iLastLut = -1;
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
word nIns = pLuts[i+1];
|
||||
word * pIns = pLuts+i+2;
|
||||
word * pT = pLuts+i+2+nIns+1;
|
||||
printf( "LUT%d : ", n );
|
||||
printf( "%02d = F( ", (int)pIns[nIns] );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
printf( "%02d ", (int)pIns[k] );
|
||||
for ( ; k < 8; k++ )
|
||||
printf( " " );
|
||||
printf( ") " );
|
||||
Extra_PrintHex2( stdout, (unsigned *)pT, nIns );
|
||||
printf( "\n" );
|
||||
}
|
||||
assert( pLuts[i] == 3+nIns+Abc_TtWordNum(nIns) );
|
||||
assert( pIns[nIns] < nVars+pLuts[0] );
|
||||
word * pIn[30], * pOut = Vec_WrdEntryP( vFuncs, nWords*pIns[nIns] );
|
||||
for ( v = 0; v < nIns; v++ )
|
||||
pIn[v] = Vec_WrdEntryP( vFuncs, nWords*pIns[v] );
|
||||
for ( m = 0; m < (1<<nIns); m++ ) {
|
||||
if ( !Abc_TtGetBit(pT, m) )
|
||||
continue;
|
||||
Abc_TtFill(pCube, nWords);
|
||||
for ( v = 0; v < nIns; v++ )
|
||||
Abc_TtAndCompl(pCube, pCube, 0, pIn[v], !((m>>v)&1), nWords);
|
||||
Abc_TtOr(pOut, pOut, pCube, nWords);
|
||||
}
|
||||
iLastLut = pIns[nIns];
|
||||
}
|
||||
word * pRes = Vec_WrdReleaseArray(vFuncs);
|
||||
Abc_TtCopy( pRes, pRes + nWords*iLastLut, nWords, 0 );
|
||||
Vec_WrdFree( vFuncs );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pLuts = Abc_LutCascadeGenTest();
|
||||
|
|
@ -198,6 +319,207 @@ word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
|||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [LUT cascade decomposition.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
// computes permutation masks for the current stage
|
||||
int Abc_TtGetGuide( char * pGuide, int Iter, Vec_Int_t * vVarIDs, int fShared )
|
||||
{
|
||||
int i, Res = 0, Count = 0;
|
||||
for ( i = 0; pGuide[i]; i++ )
|
||||
if ( pGuide[i] >= '0' && pGuide[i] <= '9' ) {
|
||||
if ( Count++ == Iter )
|
||||
break;
|
||||
}
|
||||
assert( i < strlen(pGuide) );
|
||||
assert( pGuide[i] == '0'+Iter );
|
||||
for ( i++; pGuide[i]; i++ )
|
||||
{
|
||||
char Char = pGuide[i];
|
||||
if ( Char >= '0' && Char <= '9' )
|
||||
break;
|
||||
if ( fShared && Char >= 'a' && Char <= 'z' )
|
||||
continue;
|
||||
int Value = -1;
|
||||
if ( Char >= 'a' && Char <= 'z' )
|
||||
Value = Char - 'a';
|
||||
else if ( Char >= 'A' && Char <= 'Z' )
|
||||
Value = Char - 'A';
|
||||
else assert( 0 );
|
||||
int iPlace = Vec_IntFind(vVarIDs, Value);
|
||||
assert( iPlace >= 0 );
|
||||
assert( ((Res >> iPlace) & 1) == 0 );
|
||||
Res |= 1 << iPlace;
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
// moves variables in the mask to be the last ones in the order
|
||||
void Abc_TtPermuteMask( word * p, int nVars, int Mask, Vec_Int_t * vPerm )
|
||||
{
|
||||
assert( !vPerm || nVars == Vec_IntSize(vPerm) );
|
||||
int v, i, iLast = nVars-1, nWords = Abc_TtWordNum(nVars);
|
||||
int * pPerm = vPerm ? Vec_IntArray(vPerm) : NULL;
|
||||
if ( 0 && vPerm ) {
|
||||
printf( "Beg: " );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
printf( "%c ", 'a'+Vec_IntEntry(vPerm, v) );
|
||||
printf( "\n" );
|
||||
printf( "Bit: " );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
printf( "%c ", (Mask >> v) & 1 ? '1' : '-' );
|
||||
printf( "\n" );
|
||||
}
|
||||
for ( v = nVars-1; v >= 0; v-- ) {
|
||||
if ( ((Mask >> v) & 1) == 0 )
|
||||
continue;
|
||||
if ( v == iLast ) {
|
||||
iLast--;
|
||||
continue;
|
||||
}
|
||||
assert( v < iLast );
|
||||
for ( i = v; i < iLast; i++ ) {
|
||||
Abc_TtSwapAdjacent( p, nWords, i );
|
||||
if ( pPerm ) ABC_SWAP( int, pPerm[i], pPerm[i+1] )
|
||||
}
|
||||
iLast--;
|
||||
}
|
||||
if ( 0 && vPerm ) {
|
||||
printf( "End: " );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
printf( "%c ", 'a'+Vec_IntEntry(vPerm, v) );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// checks if the given function exists in storage
|
||||
// if the function does not exist, adds it to storage
|
||||
// returns the number of the function in storage
|
||||
int Abc_LutCascadeLookup( word * pStore, int nFuncs, word * pFunc, int nWords )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nFuncs; i++ )
|
||||
if ( Abc_TtEqual( pStore+i*nWords, pFunc, nWords ) )
|
||||
return i;
|
||||
Abc_TtCopy( pStore+i*nWords, pFunc, nWords, 0 );
|
||||
assert( i == nFuncs );
|
||||
return i;
|
||||
}
|
||||
void Abc_LutCascadeDerive( word * p, int nVars, int nBVars, int Myu, word * pRem, word * pDec, int nStep )
|
||||
{
|
||||
int nFVars = nVars-nBVars; assert( nFVars >= 6 );
|
||||
int nEVars = Abc_Base2Log(Myu);
|
||||
int nFWords = Abc_TtWordNum(nFVars);
|
||||
int m, e, iFunc, nFuncs = 0;
|
||||
//printf( "Decomposition pattern with %d BS vars and %d FS vars: ", nBVars, nFVars );
|
||||
for ( m = 0; m < (1 << nBVars); m++ ) {
|
||||
iFunc = Abc_LutCascadeLookup( pRem, nFuncs, p+m*nFWords, nFWords );
|
||||
//printf( "%x", iFunc );
|
||||
nFuncs = Abc_MaxInt( nFuncs, iFunc+1 );
|
||||
for ( e = 0; e < nEVars; e++ )
|
||||
if ( (iFunc >> e) & 1 )
|
||||
Abc_TtSetBit(pDec+e*nStep, m);
|
||||
}
|
||||
//printf( "\n" );
|
||||
assert( nFuncs <= Myu );
|
||||
iFunc = nFuncs-1;
|
||||
for ( m = nFuncs; m < (1 << nEVars); m++ )
|
||||
Abc_TtCopy( pRem+m*nFWords, pRem+iFunc*nFWords, nFWords, 0 );
|
||||
if ( nBVars < 6 )
|
||||
for ( e = 0; e < nEVars; e++ )
|
||||
pDec[e*nStep] = Abc_Tt6Stretch( pDec[e*nStep], nBVars );
|
||||
}
|
||||
|
||||
// performs decomposition of one stage
|
||||
static inline int Abc_LutCascadeDecStage( char * pGuide, int Iter, Vec_Wrd_t * vFuncs[3], Vec_Int_t * vVarIDs, int nRVars, int nRails, int nLutSize, int fVerbose, Vec_Wrd_t * vCas )
|
||||
{
|
||||
extern word Abc_TtFindBVarsSVars( word * p, int nVars, int nRVars, int nRails, int nLutSize, int fVerbose );
|
||||
assert( Vec_IntSize(vVarIDs) > nLutSize );
|
||||
assert( Vec_IntSize(vVarIDs) <= 24 );
|
||||
word Guide = pGuide ? 0 : Abc_TtFindBVarsSVars( Vec_WrdArray(vFuncs[0]), Vec_IntSize(vVarIDs), nRVars, nRails, nLutSize, fVerbose );
|
||||
int m, Myu = pGuide ? 1 << nRails : (Guide >> 48) & 0xFF;
|
||||
int nEVars = Abc_Base2Log(Myu);
|
||||
if ( nEVars > nRails ) {
|
||||
printf( "Best Myu (%d) requires %d rails that is more than available (%d).\n", Myu, nEVars, nRails );
|
||||
Vec_IntClear( vVarIDs );
|
||||
return 0;
|
||||
}
|
||||
int nVars = Vec_IntSize(vVarIDs);
|
||||
int mBVars = pGuide ? Abc_TtGetGuide(pGuide, Iter, vVarIDs, 0) : Guide & 0xFFFFFF;
|
||||
int nBVars = __builtin_popcount(mBVars);
|
||||
assert( nBVars <= nLutSize );
|
||||
Abc_TtPermuteMask( Vec_WrdArray(vFuncs[0]), nVars, mBVars, vVarIDs );
|
||||
int mSVars = pGuide ? Abc_TtGetGuide(pGuide, Iter, vVarIDs, 1) : (Guide >> 24) & 0xFFFFFF;
|
||||
int nSVars = __builtin_popcount(mSVars);
|
||||
Abc_TtPermuteMask( Vec_WrdArray(vFuncs[0]), nVars, mSVars, vVarIDs );
|
||||
// prepare function (nVars -> nAVars+nVars)
|
||||
int nFVars = nVars - nBVars;
|
||||
int nAVars = nFVars >= 6 ? 0 : 6-nFVars;
|
||||
int nWordsNew = Abc_TtWordNum(nVars+nAVars);
|
||||
Vec_WrdFillExtra( vFuncs[0], nWordsNew, 0 );
|
||||
word * pFunc = Vec_WrdArray(vFuncs[0]);
|
||||
Abc_TtStretch6( pFunc, nVars, nVars+nAVars );
|
||||
Abc_TtPermuteMask( pFunc, nVars+nAVars, (1 << nVars)-1, NULL );
|
||||
// prepare remainder function (nAVars+nFVars+nEVars+nSVars)
|
||||
int nWordsRem = Abc_TtWordNum(nAVars+nFVars+nEVars+nSVars);
|
||||
Vec_WrdFill( vFuncs[1], nWordsRem, 0 );
|
||||
word * pRem = Vec_WrdArray(vFuncs[1]);
|
||||
// prepare decomposed functions (nBVars+nZVars) * nEVars
|
||||
int nUVars = nBVars - nSVars;
|
||||
int nZVars = nUVars >= 6 ? 0 : 6-nUVars;
|
||||
int nWordsDec = Abc_TtWordNum(nBVars+nZVars);
|
||||
int nWordsStep = Abc_TtWordNum(nUVars+nZVars);
|
||||
Vec_WrdFill( vFuncs[2], nWordsDec*nEVars, 0 );
|
||||
word * pDec = Vec_WrdArray(vFuncs[2]);
|
||||
int nSMints = 1 << nSVars;
|
||||
for ( m = 0; m < nSMints; m++ )
|
||||
Abc_LutCascadeDerive(pFunc+m*nWordsNew/nSMints, nVars+nAVars-nSVars, nBVars-nSVars, Myu,
|
||||
pRem+m*nWordsRem/nSMints, pDec+m*nWordsStep, nWordsDec );
|
||||
Abc_TtPermuteMask( pRem, nAVars+nFVars+nEVars+nSVars, (1 << nAVars)-1, NULL );
|
||||
Abc_TtPermuteMask( pRem, nFVars+nEVars+nSVars, ((1 << nEVars)-1) << nFVars, NULL );
|
||||
for ( m = 0; m < nEVars; m++ )
|
||||
Abc_TtPermuteMask( pDec+m*nWordsDec, nUVars+nZVars+nSVars, ((1 << nZVars)-1) << nUVars, NULL );
|
||||
for ( m = 0; m < nEVars; m++ )
|
||||
Abc_LutCascadeGenOne( vCas, nBVars, Vec_IntArray(vVarIDs)+nVars-nBVars, Vec_WrdEntry(vCas,0), pDec+m*nWordsDec );
|
||||
Abc_TtCopy( pFunc, pRem, Abc_TtWordNum(nFVars+nSVars+nEVars), 0 );
|
||||
assert( nEVars < nUVars );
|
||||
for ( m = 0; m < nSVars; m++ )
|
||||
Vec_IntWriteEntry(vVarIDs, nFVars+m, Vec_IntEntry(vVarIDs, nVars-nSVars+m) );
|
||||
for ( m = 0; m < nEVars; m++ )
|
||||
Vec_IntWriteEntry(vVarIDs, nFVars+nSVars+m, Vec_WrdEntry(vCas,0)-nEVars+m );
|
||||
Vec_IntShrink( vVarIDs, nFVars+nSVars+nEVars );
|
||||
return nEVars;
|
||||
}
|
||||
static inline word * Abc_LutCascadeDec( char * pGuide, word * pTruth, Vec_Int_t * vVarIDs, int nRails, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pRes = NULL; int i, nRVars = 0, nVars = Vec_IntSize(vVarIDs);
|
||||
Vec_Wrd_t * vFuncs[3] = { Vec_WrdStart(Abc_TtWordNum(nVars)), Vec_WrdAlloc(0), Vec_WrdAlloc(0) };
|
||||
Abc_TtCopy( Vec_WrdArray(vFuncs[0]), pTruth, Abc_TtWordNum(nVars), 0 );
|
||||
Vec_Wrd_t * vCas = Vec_WrdAlloc( 100 ); Vec_WrdPush( vCas, nVars );
|
||||
for ( i = 0; Vec_IntSize(vVarIDs) > nLutSize; i++ )
|
||||
nRVars = Abc_LutCascadeDecStage( pGuide, i, vFuncs, vVarIDs, nRVars, nRails, nLutSize, fVerbose, vCas );
|
||||
if ( Vec_IntSize(vVarIDs) > 0 ) {
|
||||
Abc_LutCascadeGenOne( vCas, Vec_IntSize(vVarIDs), Vec_IntArray(vVarIDs), Vec_WrdEntry(vCas, 0), Vec_WrdArray(vFuncs[0]) );
|
||||
Vec_WrdAddToEntry( vCas, 0, -nVars );
|
||||
pRes = Vec_WrdReleaseArray(vCas);
|
||||
}
|
||||
Vec_WrdFree( vCas );
|
||||
for ( i = 0; i < 3; i++ )
|
||||
Vec_WrdFree( vFuncs[i] );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -225,11 +547,30 @@ Abc_Obj_t * Abc_NtkLutCascadeDeriveSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeNe
|
|||
return pNodeNew;
|
||||
}
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, int nVars, Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 ); word n, i, k, iLastLut = -1;
|
||||
assert( Abc_NtkCoNum(pNtk) == 1 );
|
||||
Abc_Ntk_t * pNtkNew = NULL;
|
||||
Abc_Obj_t * pObj; int Id; char pName[2] = {0};
|
||||
Vec_Ptr_t * vCopy = Vec_PtrStart( nVars + pLuts[0] + 1000 );
|
||||
if ( pNtk ) {
|
||||
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
|
||||
}
|
||||
else {
|
||||
pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP , 0 );
|
||||
pNtkNew->pName = Extra_UtilStrsav("cas");
|
||||
//pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
|
||||
for ( Id = 0; Id < nVars; Id++ ) {
|
||||
pObj = Abc_NtkCreatePi(pNtkNew);
|
||||
pName[0] = 'a' + Id;
|
||||
Abc_ObjAssignName( pObj, pName, NULL );
|
||||
}
|
||||
pObj = Abc_NtkCreatePo(pNtkNew);
|
||||
Abc_ObjAssignName( pObj, "Out", NULL );
|
||||
}
|
||||
Abc_NtkForEachCi( pNtkNew, pObj, Id )
|
||||
Vec_PtrWriteEntry( vCopy, Id, pObj );
|
||||
Vec_Int_t * vCover = Vec_IntAlloc( 1000 );
|
||||
word n, i, k, iLastLut = -1;
|
||||
for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
|
||||
{
|
||||
word nIns = pLuts[i+1];
|
||||
|
|
@ -237,12 +578,15 @@ Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, Abc_Ntk_t * pNtk, int nLutS
|
|||
word * pT = pLuts+i+2+nIns+1;
|
||||
Abc_Obj_t * pNodeNew = Abc_NtkCreateNode( pNtkNew );
|
||||
for ( k = 0; k < nIns; k++ )
|
||||
Abc_ObjAddFanin( pNodeNew, Abc_NtkCi(pNtk, pIns[k])->pCopy );
|
||||
Abc_NtkCi(pNtk, pIns[nIns])->pCopy = Abc_NtkLutCascadeDeriveSop( pNtkNew, pNodeNew, pT, nIns, vCover );
|
||||
Abc_ObjAddFanin( pNodeNew, (Abc_Obj_t *)Vec_PtrEntry(vCopy, pIns[k]) );
|
||||
Abc_Obj_t * pObjNew = Abc_NtkLutCascadeDeriveSop( pNtkNew, pNodeNew, pT, nIns, vCover );
|
||||
Vec_PtrWriteEntry( vCopy, pIns[nIns], pObjNew );
|
||||
iLastLut = pIns[nIns];
|
||||
}
|
||||
Vec_IntFree( vCover );
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtk, 0)->pCopy, Abc_NtkCi(pNtk, iLastLut)->pCopy );
|
||||
assert( Abc_NtkCoNum(pNtkNew) == 1 );
|
||||
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, 0), (Abc_Obj_t *)Vec_PtrEntry(vCopy, iLastLut) );
|
||||
Vec_PtrFree( vCopy );
|
||||
if ( !Abc_NtkCheck( pNtkNew ) )
|
||||
{
|
||||
printf( "Abc_NtkLutCascadeFromLuts: The network check has failed.\n" );
|
||||
|
|
@ -260,22 +604,65 @@ Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nR
|
|||
Mini_Aig_t * pM = Gia_ManToMiniAig( pGia );
|
||||
//word * pLuts = Abc_LutCascade( pM, nLutSize, nLuts, nRails, nIters, fVerbose );
|
||||
word * pLuts = Abc_LutCascadeTest( pM, nLutSize, 0 );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, pNtk, nLutSize, fVerbose ) : NULL;
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, Abc_NtkCiNum(pNtk), pNtk, nLutSize, fVerbose ) : NULL;
|
||||
ABC_FREE( pLuts );
|
||||
Mini_AigStop( pM );
|
||||
Gia_ManStop( pGia );
|
||||
return pNew;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascade2( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose )
|
||||
Abc_Ntk_t * Abc_NtkLutCascade2( Abc_Ntk_t * pNtk, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose, char * pGuide )
|
||||
{
|
||||
extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
|
||||
extern word * Abc_LutCascade2( word * p, int nVars, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose );
|
||||
extern word * Abc_LutCascade2( word * p, int nVars, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose );
|
||||
Gia_Man_t * pGia = Abc_NtkStrashToGia( pNtk );
|
||||
word * pTruth = Gia_ObjComputeTruthTable( pGia, Gia_ManCo(pGia, 0) );
|
||||
word * pLuts = Abc_LutCascade2( pTruth, Gia_ManCiNum(pGia), nLutSize, nLuts, nRails, nIters, fVerbose );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, pNtk, nLutSize, fVerbose ) : NULL;
|
||||
ABC_FREE( pLuts );
|
||||
word * pTruth1 = Gia_ObjComputeTruthTable( pGia, Gia_ManCo(pGia, 0) );
|
||||
|
||||
int nVars = Abc_NtkCiNum(pNtk);
|
||||
Vec_Int_t * vVarIDs = Vec_IntStartNatural( nVars );
|
||||
Abc_TtMinimumBase( pTruth1, Vec_IntArray(vVarIDs), nVars, &nVars );
|
||||
if ( fVerbose ) {
|
||||
if ( Vec_IntSize(vVarIDs) != nVars )
|
||||
printf( "The support of the function is reduced from %d to %d variables.\n", Vec_IntSize(vVarIDs), nVars );
|
||||
printf( "Decomposing %d-var function into %d-rail cascade of %d-LUTs", nVars, nRails, nLutSize );
|
||||
if ( pGuide )
|
||||
printf( " using structural info: %s", pGuide );
|
||||
printf( ".\n" );
|
||||
}
|
||||
Vec_IntShrink( vVarIDs, nVars );
|
||||
|
||||
//word * pLuts = Abc_LutCascade2( pTruth1, nVars, nLutSize, nLuts, nRails, nIters, fVerbose );
|
||||
word * pLuts = Abc_LutCascadeDec( pGuide, pTruth1, vVarIDs, nRails, nLutSize, fVerbose );
|
||||
Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, nVars, pNtk, nLutSize, fVerbose ) : NULL;
|
||||
Vec_IntFree( vVarIDs );
|
||||
|
||||
if ( pLuts && fVerbose ) {
|
||||
word * pTruth2 = Abc_LutCascadeTruth( pLuts, Abc_NtkCiNum(pNtk) );
|
||||
if ( nVars < 9 ) {
|
||||
printf("Function before: "); Abc_TtPrintHexRev( stdout, pTruth1, nVars ); printf( "\n" );
|
||||
printf("Function after: "); Abc_TtPrintHexRev( stdout, pTruth2, nVars ); printf( "\n" );
|
||||
}
|
||||
Abc_LutCascadePrint( pLuts );
|
||||
ABC_FREE( pLuts );
|
||||
ABC_FREE( pTruth2 );
|
||||
}
|
||||
Gia_ManStop( pGia );
|
||||
//ABC_FREE( pTruth1 );
|
||||
return pNew;
|
||||
}
|
||||
Abc_Ntk_t * Abc_NtkLutCascadeGen( int nLutSize, int nStages, int nRails, int nShared, int fVerbose )
|
||||
{
|
||||
int nVars = nStages * nLutSize - (nStages-1) * (nRails + nShared);
|
||||
word * pLuts = Abc_LutCascadeGen( nVars, nLutSize, nRails, nShared );
|
||||
Abc_Ntk_t * pNew = Abc_NtkLutCascadeFromLuts( pLuts, nVars, NULL, nLutSize, fVerbose );
|
||||
Abc_LutCascadePrint( pLuts );
|
||||
if ( fVerbose ) {
|
||||
word * pTruth = Abc_LutCascadeTruth( pLuts, nVars );
|
||||
if ( nVars <= 10 ) {
|
||||
printf( "Function: "); Abc_TtPrintHexRev( stdout, pTruth, nVars ); printf( "\n" );
|
||||
}
|
||||
ABC_FREE( pTruth );
|
||||
}
|
||||
ABC_FREE( pLuts );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -773,39 +773,6 @@ void Abc_BSEvalBestGen( int nVars, int nBVars, int nFuncs, int nMints, int fTryA
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Vec_Wrd_t * Vec_WrdStartTruthTables6( int nVars )
|
||||
{
|
||||
Vec_Wrd_t * p;
|
||||
word Masks[6] = {
|
||||
ABC_CONST(0xAAAAAAAAAAAAAAAA),
|
||||
ABC_CONST(0xCCCCCCCCCCCCCCCC),
|
||||
ABC_CONST(0xF0F0F0F0F0F0F0F0),
|
||||
ABC_CONST(0xFF00FF00FF00FF00),
|
||||
ABC_CONST(0xFFFF0000FFFF0000),
|
||||
ABC_CONST(0xFFFFFFFF00000000)
|
||||
};
|
||||
int i, k, nWords = nVars <= 6 ? 1 : (1 << (nVars - 6));
|
||||
p = Vec_WrdStart( nWords * nVars );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
word * pTruth = p->pArray + nWords * i;
|
||||
if ( i < 6 )
|
||||
{
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
pTruth[k] = Masks[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
if ( k & (1 << (i-6)) )
|
||||
pTruth[k] = ~(word)0;
|
||||
else
|
||||
pTruth[k] = 0;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void Abc_BSEvalCreateCofs( int iSet, int nVars, Vec_Wrd_t * vCofs, Vec_Wrd_t * vElems )
|
||||
{
|
||||
int nWords = Abc_Truth6WordNum(nVars);
|
||||
|
|
@ -990,6 +957,76 @@ word * Abc_LutCascade2( word * pFunc, int nVars, int nLutSize, int nLuts, int nR
|
|||
return pRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Computes bound set and shared set of the next stage.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
word Abc_TtFindBVarsSVars( word * pTruth, int nVars, int nRVars, int nRails, int nLutSize, int fVerbose )
|
||||
{
|
||||
Abc_BSEval_t * p = Abc_BSEvalAlloc();
|
||||
int nPermVars = nVars-nRVars;
|
||||
if ( p->nVars != nPermVars || p->nBVars != nLutSize ) {
|
||||
if ( p->nBVars != nLutSize ) {
|
||||
Vec_WecFreeP( &p->vSets );
|
||||
Vec_WrdFreeP( &p->vCofs );
|
||||
p->vCofs = Abc_BSEvalCreateCofactorSets( nLutSize, &p->vSets );
|
||||
}
|
||||
Vec_IntFreeP( &p->vPairs );
|
||||
p->vPairs = Abc_GenChasePairs( nPermVars, nLutSize );
|
||||
p->nVars = nPermVars;
|
||||
p->nBVars = nLutSize;
|
||||
}
|
||||
|
||||
int v, nWords = Abc_TtWordNum(nVars);
|
||||
word * pCopy = ABC_ALLOC( word, nWords );
|
||||
Abc_TtCopy( pCopy, pTruth, nWords, 0 );
|
||||
word pPat[1024];
|
||||
|
||||
|
||||
int pPermBest[32] = {0};
|
||||
word * pBest = ABC_ALLOC( word, nWords );
|
||||
//printf("Function before: "); Abc_TtPrintHexRev( stdout, pCopy, nVars ); printf( "\n" );
|
||||
int MyuMin = Abc_BSEvalBest( p, pCopy, pBest, nVars, nRVars, nVars-nLutSize, 0, pPermBest, 0 );
|
||||
//printf("Function before: "); Abc_TtPrintHexRev( stdout, pCopy, nVars ); printf( "\n" );
|
||||
|
||||
if ( fVerbose ) {
|
||||
printf( "Best perm: " );
|
||||
for ( v = 0; v < nVars; v++ )
|
||||
printf( "%d ", pPermBest[v] );
|
||||
printf( " Myu = %d. ", MyuMin );
|
||||
}
|
||||
|
||||
int Shared = 0, nRailsMin = Abc_Base2Log( MyuMin );
|
||||
if ( nRailsMin > nRails ) {
|
||||
nRailsMin = Abc_SharedEvalBest( p, pBest, nVars, nRVars, nVars-nLutSize, MyuMin, nRails, 0, &Shared, pPat );
|
||||
MyuMin = 1 << nRailsMin;
|
||||
}
|
||||
|
||||
if ( fVerbose )
|
||||
printf( "Myu min = %d. Rail min = %d. Shared = %x.\n", MyuMin, nRailsMin, Shared );
|
||||
|
||||
word mBVars = 0;
|
||||
for ( v = 0; v < nLutSize; v++ )
|
||||
mBVars |= (word)1 << pPermBest[nVars-nLutSize+v];
|
||||
|
||||
word mSVars = 0;
|
||||
for ( v = 0; v < nLutSize; v++ )
|
||||
if ( (Shared >> v) & 1 )
|
||||
mSVars |= (word)1 << (nVars-nLutSize+v);
|
||||
|
||||
ABC_FREE( pCopy );
|
||||
ABC_FREE( pBest );
|
||||
Abc_BSEvalFree(p);
|
||||
return ((word)MyuMin << 48) | (mSVars << 24) | mBVars;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -2007,6 +2007,27 @@ static inline word Abc_Tt6RemoveVar( word t, int iVar )
|
|||
t = Abc_Tt6SwapAdjacent( t, iVar++ );
|
||||
return t;
|
||||
}
|
||||
// permutes two variables while keeping track of their places
|
||||
static inline void Abc_TtPermuteTwo( word * p, int nTTVars, int * Var2Pla, int * Pla2Var, int Var0, int Var1 )
|
||||
{
|
||||
int iPlace0 = Var2Pla[Var0];
|
||||
int iPlace1 = Var2Pla[Var1];
|
||||
if ( iPlace0 == iPlace1 )
|
||||
return;
|
||||
Abc_TtSwapVars( p, nTTVars, iPlace0, iPlace1 );
|
||||
Var2Pla[Pla2Var[iPlace0]] = iPlace1;
|
||||
Var2Pla[Pla2Var[iPlace1]] = iPlace0;
|
||||
Pla2Var[iPlace0] ^= Pla2Var[iPlace1];
|
||||
Pla2Var[iPlace1] ^= Pla2Var[iPlace0];
|
||||
Pla2Var[iPlace0] ^= Pla2Var[iPlace1];
|
||||
}
|
||||
// restores natural variable order
|
||||
static inline void Abc_TtRestoreOrder( word * p, int nTTVars, int * Var2Pla, int * Pla2Var, int nPermVars )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < nPermVars; i++ )
|
||||
Abc_TtPermuteTwo( p, nTTVars, Var2Pla, Pla2Var, i, Var2Pla[i] );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -221,6 +221,37 @@ static inline Vec_Wrd_t * Vec_WrdStartTruthTablesRev( int nVars )
|
|||
}
|
||||
return p;
|
||||
}
|
||||
static inline Vec_Wrd_t * Vec_WrdStartTruthTables6( int nVars )
|
||||
{
|
||||
word Masks[6] = {
|
||||
ABC_CONST(0xAAAAAAAAAAAAAAAA),
|
||||
ABC_CONST(0xCCCCCCCCCCCCCCCC),
|
||||
ABC_CONST(0xF0F0F0F0F0F0F0F0),
|
||||
ABC_CONST(0xFF00FF00FF00FF00),
|
||||
ABC_CONST(0xFFFF0000FFFF0000),
|
||||
ABC_CONST(0xFFFFFFFF00000000)
|
||||
};
|
||||
int i, k, nWords = nVars <= 6 ? 1 : (1 << (nVars - 6));
|
||||
Vec_Wrd_t * p = Vec_WrdStart( nWords * nVars );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
{
|
||||
word * pTruth = p->pArray + nWords * i;
|
||||
if ( i < 6 )
|
||||
{
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
pTruth[k] = Masks[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( k = 0; k < nWords; k++ )
|
||||
if ( k & (1 << (i-6)) )
|
||||
pTruth[k] = ~(word)0;
|
||||
else
|
||||
pTruth[k] = 0;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
static inline int Vec_WrdShiftOne( Vec_Wrd_t * p, int nWords )
|
||||
{
|
||||
int i, nObjs = p->nSize/nWords;
|
||||
|
|
|
|||
Loading…
Reference in New Issue