mirror of https://github.com/YosysHQ/abc.git
Experiments with LUT cascade mapping.
This commit is contained in:
parent
4ac014db41
commit
6d6a5accb4
|
|
@ -8927,11 +8927,11 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
{
|
||||
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 );
|
||||
extern void Abc_NtkLutCascadeFile( char * pFileName, int nVarNum, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose );
|
||||
extern void Abc_NtkLutCascadeFile( char * pFileName, int nVarNum, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose, int fVeryVerbose );
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pNtkRes; char * pGuide = NULL, * pFileName = NULL;
|
||||
int c, nVarNum = -1, nLutSize = 6, nStages = 8, nRails = 1, nShared = 2, nIters = 1, fGen = 0, fVerbose = 0;
|
||||
int c, nVarNum = -1, nLutSize = 6, nStages = 8, nRails = 1, nShared = 2, nIters = 1, fGen = 0, fVerbose = 0, fVeryVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KMRSINFgvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KMRSINFgvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -9016,6 +9016,9 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'w':
|
||||
fVeryVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
|
|
@ -9029,7 +9032,7 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Print( -1, "The number of variables should be given on the command line using switch \"-N <num>\".\n" );
|
||||
return 1;
|
||||
}
|
||||
Abc_NtkLutCascadeFile( pFileName, nVarNum, nLutSize, nStages, nRails, nIters, fVerbose );
|
||||
Abc_NtkLutCascadeFile( pFileName, nVarNum, nLutSize, nStages, nRails, nIters, fVerbose, fVeryVerbose );
|
||||
return 1;
|
||||
}
|
||||
if ( fGen )
|
||||
|
|
@ -9076,7 +9079,7 @@ int Abc_CommandLutCasDec( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: lutcasdec [-KMRSIN <num>] [-F <file>] [-vh]\n" );
|
||||
Abc_Print( -2, "usage: lutcasdec [-KMRSIN <num>] [-F <file>] [-vwh]\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-M <num> : the maximum delay (the number of stages) [default = %d]\n", nStages );
|
||||
|
|
@ -9087,6 +9090,7 @@ usage:
|
|||
Abc_Print( -2, "\t-F <file>: a text file with truth tables in hexadecimal listed one per line\n");
|
||||
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-w : toggle additional verbose printout [default = %s]\n", fVerbose? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,7 +310,10 @@ word * Abc_LutCascadeTruth( word * pLuts, int nVars )
|
|||
Vec_WrdFree( vFuncs );
|
||||
return pRes;
|
||||
}
|
||||
|
||||
int Abc_LutCascadeCount( word * pLuts )
|
||||
{
|
||||
return (int)pLuts[0];
|
||||
}
|
||||
word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
|
||||
{
|
||||
word * pLuts = Abc_LutCascadeGenTest();
|
||||
|
|
@ -447,13 +450,14 @@ static inline int Abc_LutCascadeDecStage( char * pGuide, int Iter, Vec_Wrd_t * v
|
|||
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 );
|
||||
if ( !pGuide && !Guide ) {
|
||||
if ( fVerbose )
|
||||
printf( "The function is not decomposable with %d rails.\n", nRails );
|
||||
Vec_IntClear( vVarIDs );
|
||||
return -1;
|
||||
}
|
||||
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);
|
||||
|
|
@ -506,9 +510,12 @@ word * Abc_LutCascadeDec( char * pGuide, word * pTruth, Vec_Int_t * vVarIDs, int
|
|||
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++ )
|
||||
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 ) {
|
||||
if ( nRVars == -1 )
|
||||
break;
|
||||
}
|
||||
if ( nRVars != -1 && 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);
|
||||
|
|
@ -1137,62 +1144,84 @@ Vec_Wrd_t * Abc_NtkLutCasReadTruths( char * pFileName, int nVarNum )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_NtkLutCascadeFile( char * pFileName, int nVarNum, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose )
|
||||
void Abc_NtkLutCascadeFile( char * pFileName, int nVarNum, int nLutSize, int nLuts, int nRails, int nIters, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
int nWords = Abc_TtWordNum(nVarNum);
|
||||
Vec_Wrd_t * vTruths = Abc_NtkLutCasReadTruths( pFileName, nVarNum );
|
||||
abctime clkStart = Abc_Clock();
|
||||
int i, Sum = 0, nWords = Abc_TtWordNum(nVarNum);
|
||||
Vec_Wrd_t * vTruths = NULL;
|
||||
if ( strstr(pFileName, ".txt") )
|
||||
vTruths = Abc_NtkLutCasReadTruths( pFileName, nVarNum );
|
||||
else
|
||||
vTruths = Vec_WrdReadBin( pFileName, 0 );
|
||||
if ( vTruths == NULL )
|
||||
return;
|
||||
|
||||
word * pCopy = ABC_ALLOC( word, nWords );
|
||||
int nFuncs = Vec_WrdSize(vTruths)/nWords;
|
||||
if ( Vec_WrdSize(vTruths) != nFuncs * nWords ) {
|
||||
printf( "The files size (%d bytes) does not match the truth table size (%d) for the given number of functions (%d).\n", 8*Vec_WrdSize(vTruths), 8*nWords, nFuncs );
|
||||
Vec_WrdFree( vTruths );
|
||||
return;
|
||||
}
|
||||
|
||||
printf( "Considering %d functions having %d variables from file \"%s\".\n", nFuncs, nVarNum, pFileName );
|
||||
for ( int i = 0; i < nFuncs; i++ )
|
||||
word * pCopy = ABC_ALLOC( word, nWords );
|
||||
int LutStats[100] = {0};
|
||||
for ( i = 0; i < nFuncs; i++ )
|
||||
{
|
||||
word * pTruth = Vec_WrdEntryP( vTruths, i*nWords );
|
||||
Abc_TtCopy( pCopy, pTruth, nWords, 0 );
|
||||
|
||||
if ( fVerbose )
|
||||
if ( fVeryVerbose )
|
||||
printf( "\n" );
|
||||
printf( "Function %3d : ", i );
|
||||
if ( fVerbose )
|
||||
if ( fVerbose || fVeryVerbose )
|
||||
printf( "Function %3d : ", i );
|
||||
if ( fVeryVerbose )
|
||||
Abc_TtPrintHexRev( stdout, pTruth, nVarNum ), printf( "\n" );
|
||||
//continue;
|
||||
|
||||
int nVars = nVarNum;
|
||||
Vec_Int_t * vVarIDs = Vec_IntStartNatural( nVars );
|
||||
Abc_TtMinimumBase( pTruth, Vec_IntArray(vVarIDs), nVars, &nVars );
|
||||
if ( fVerbose ) {
|
||||
if ( fVeryVerbose ) {
|
||||
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.\n", nVars, nRails, nLutSize );
|
||||
}
|
||||
Vec_IntShrink( vVarIDs, nVars );
|
||||
|
||||
word * pLuts = Abc_LutCascadeDec( NULL, pTruth, vVarIDs, nRails, nLutSize, fVerbose );
|
||||
word * pLuts = Abc_LutCascadeDec( NULL, pTruth, vVarIDs, nRails, nLutSize, fVeryVerbose );
|
||||
Vec_IntFree( vVarIDs );
|
||||
if ( pLuts == NULL ) {
|
||||
printf( "Not decomposable.\n" );
|
||||
if ( fVerbose || fVeryVerbose )
|
||||
printf( "Not decomposable.\n" );
|
||||
continue;
|
||||
}
|
||||
Sum++;
|
||||
LutStats[Abc_LutCascadeCount(pLuts)]++;
|
||||
int nWords2 = Abc_TtWordNum(nVars);
|
||||
word * pTruth2 = Abc_LutCascadeTruth( pLuts, nVars );
|
||||
if ( fVerbose )
|
||||
if ( fVeryVerbose )
|
||||
Abc_LutCascadePrint( pLuts );
|
||||
else
|
||||
if ( fVerbose || fVeryVerbose )
|
||||
printf( "Decomposition exists. " );
|
||||
if ( !Abc_TtEqual(pTruth, pTruth2, nWords2) ) {
|
||||
printf( "Verification FAILED.\n" );
|
||||
Abc_TtPrintHexRev( stdout, pCopy, nVarNum ), printf( "\n" );
|
||||
printf( "Verification FAILED for function %d.\n", i );
|
||||
Abc_TtPrintHexRev( stdout, pTruth, nVarNum ), printf( "\n" );
|
||||
}
|
||||
else
|
||||
else if ( fVerbose || fVeryVerbose )
|
||||
printf( "Verification passed.\n" );
|
||||
ABC_FREE( pTruth2 );
|
||||
ABC_FREE( pLuts );
|
||||
}
|
||||
ABC_FREE( pCopy );
|
||||
Vec_WrdFree( vTruths );
|
||||
printf( "Finished decomposing functions from file \"%s\".\n", pFileName );
|
||||
printf( "Statistics for %d-rail LUT cascade:\n", nRails );
|
||||
for ( i = 0; i < 100; i++ )
|
||||
if ( LutStats[i] )
|
||||
printf( " %d LUT6 : Function count = %8d (%6.2f %%)\n", i, LutStats[i], 100.0*LutStats[i]/nFuncs );
|
||||
printf( "Non-decomp : Function count = %8d (%6.2f %%)\n", nFuncs-Sum, 100.0*(nFuncs-Sum)/Abc_MaxInt(1, nFuncs) );
|
||||
printf( "Finished %d functions (speed = %.2f functions / second). ", nFuncs, 1.0*nFuncs/(((double)(Abc_Clock() - clkStart))/((double)CLOCKS_PER_SEC)) );
|
||||
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -589,7 +589,7 @@ int Abc_BSEvalBest( Abc_BSEval_t * p, word * pIn, word * pBest, int nVars, int n
|
|||
{
|
||||
int i, k, Var0, Var1, Pla2Var[32], Var2Pla[32];
|
||||
int nPermVars = nVars-nCVars;
|
||||
assert( p->nVars == nPermVars && p->nBVars == nPermVars-nFVars );
|
||||
assert( p->nVars == nPermVars && p->nBVars == nVars-nFVars );
|
||||
for ( i = 0; i < nVars; i++ )
|
||||
Pla2Var[i] = Var2Pla[i] = i;
|
||||
if ( pPermBest )
|
||||
|
|
@ -617,8 +617,20 @@ int Abc_BSEvalBest( Abc_BSEval_t * p, word * pIn, word * pBest, int nVars, int n
|
|||
for ( k = nFVars-1; k >= 0; k-- )
|
||||
printf( " %d", Pla2Var[k] );
|
||||
printf( " : Myu = %3d", CostThis );
|
||||
printf( "\n" );
|
||||
//printf( "\n" );
|
||||
}
|
||||
if ( 0 ) {
|
||||
word pPat[1024];
|
||||
int nRails = 1, Shared = 0;
|
||||
if ( CostThis > (1 << nRails) ) {
|
||||
extern int Abc_SharedEvalBest( Abc_BSEval_t * p, word * pTruth, int nVars, int nCVars, int nFVars, int MyuMin, int nRails, int fVerbose, int * pSetShared, word * pPat );
|
||||
int nRailsMin = Abc_SharedEvalBest( p, pIn, nVars, nCVars, nFVars, CostThis, nRails, 0, &Shared, pPat );
|
||||
printf( " RailMin = %d. Shared = %2d. ", nRailsMin, Shared );
|
||||
}
|
||||
}
|
||||
if ( fVerbose )
|
||||
printf( "\n" );
|
||||
|
||||
int iPlace0 = Var2Pla[Var0];
|
||||
int iPlace1 = Var2Pla[Var1];
|
||||
if ( iPlace0 == iPlace1 )
|
||||
|
|
@ -859,17 +871,19 @@ int Abc_BSEvalFindShared( int nVars, word * pISets, int nISets, int nBSWords, Ve
|
|||
***********************************************************************/
|
||||
int Abc_SharedEvalBest( Abc_BSEval_t * p, word * pTruth, int nVars, int nCVars, int nFVars, int MyuMin, int nRails, int fVerbose, int * pSetShared, word * pPat )
|
||||
{
|
||||
int nBSWords = Abc_Truth6WordNum( nVars - nFVars ), CVarMask = Abc_InfoMask(nCVars) << (nVars - nFVars - nCVars);
|
||||
int nBSWords = Abc_Truth6WordNum( nVars - nFVars ), CVarMask = nCVars ? Abc_InfoMask(nCVars) << (nVars - nCVars - nFVars) : 0;
|
||||
int MyuCur, Myu = Abc_TtGetCMInt( pTruth, nVars, nFVars, p->vCounts, p->vTable, p->vStore, p->vUsed, pPat );
|
||||
int nRailsCur = Abc_Base2Log( Myu ); Vec_Int_t * vLevel;
|
||||
assert( Myu == MyuMin && nRailsCur > nRails );
|
||||
int i, k, iSet, iStart, nSharedMax = nVars - nFVars - 1, nRailsMin = 100;
|
||||
Vec_WecForEachLevelStartStop( p->vSets, vLevel, i, 1, nSharedMax+1 ) {
|
||||
int i, k, iSet, iStart, nSharedMax = nVars - nCVars - nFVars - 1, nRailsMin = 100;
|
||||
Vec_WecForEachLevelStartStop( p->vSets, vLevel, i, 1, nSharedMax ) {
|
||||
Vec_IntForEachEntryDouble( vLevel, iSet, iStart, k ) {
|
||||
if ( iSet & CVarMask )
|
||||
continue;
|
||||
//printf( "\nTrying set " ); Extra_PrintBinary( stdout, &iSet, nVars-nFVars ); printf( "\n" );
|
||||
MyuCur = Abc_BSEvalCountUniqueMax( pPat, Myu, nBSWords, Vec_WrdEntryP(p->vCofs, iStart), i, 1 << nRails );
|
||||
if ( MyuCur == 0 )
|
||||
//printf( " Res = %d", MyuCur );
|
||||
if ( MyuCur == 0 || MyuCur > (1 << nRails) )
|
||||
continue;
|
||||
nRailsCur = Abc_Base2Log(MyuCur);
|
||||
if ( nRailsCur > nRails )
|
||||
|
|
@ -972,23 +986,24 @@ word Abc_TtFindBVarsSVars( word * pTruth, int nVars, int nRVars, int nRails, int
|
|||
{
|
||||
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 );
|
||||
}
|
||||
if ( p->nVars != nPermVars ) {
|
||||
Vec_IntFreeP( &p->vPairs );
|
||||
p->vPairs = Abc_GenChasePairs( nPermVars, nLutSize );
|
||||
p->nVars = nPermVars;
|
||||
p->nBVars = nLutSize;
|
||||
p->vPairs = Abc_GenChasePairs( nPermVars, nLutSize-nRVars );
|
||||
p->nVars = nPermVars;
|
||||
}
|
||||
if ( p->nBVars != nLutSize ) {
|
||||
Vec_WecFreeP( &p->vSets );
|
||||
Vec_WrdFreeP( &p->vCofs );
|
||||
p->vCofs = Abc_BSEvalCreateCofactorSets( nLutSize, &p->vSets );
|
||||
p->nBVars = nLutSize;
|
||||
}
|
||||
|
||||
int v, nWords = Abc_TtWordNum(nVars);
|
||||
word * pCopy = ABC_ALLOC( word, nWords );
|
||||
Abc_TtCopy( pCopy, pTruth, nWords, 0 );
|
||||
word pPat[1024];
|
||||
|
||||
//Abc_TtPrintHexRev( stdout, pTruth, nVars ); printf( "\n" );
|
||||
|
||||
int pPermBest[32] = {0};
|
||||
word * pBest = ABC_ALLOC( word, nWords );
|
||||
|
|
@ -1009,9 +1024,16 @@ word Abc_TtFindBVarsSVars( word * pTruth, int nVars, int nRVars, int nRails, int
|
|||
MyuMin = 1 << nRailsMin;
|
||||
}
|
||||
|
||||
ABC_FREE( pCopy );
|
||||
ABC_FREE( pBest );
|
||||
Abc_BSEvalFree(p);
|
||||
|
||||
if ( fVerbose )
|
||||
printf( "Myu min = %d. Rail min = %d. Shared = %x.\n", MyuMin, nRailsMin, Shared );
|
||||
|
||||
if ( nRailsMin > nRails )
|
||||
return 0;
|
||||
|
||||
word mBVars = 0;
|
||||
for ( v = 0; v < nLutSize; v++ )
|
||||
mBVars |= (word)1 << pPermBest[nVars-nLutSize+v];
|
||||
|
|
@ -1021,9 +1043,6 @@ word Abc_TtFindBVarsSVars( word * pTruth, int nVars, int nRVars, int nRails, int
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue