mirror of https://github.com/YosysHQ/abc.git
Updating LUT synthesis code.
This commit is contained in:
parent
e6a47c3e41
commit
ed13c6d4d2
|
|
@ -34,8 +34,6 @@ ABC_NAMESPACE_IMPL_START
|
||||||
/// DECLARATIONS ///
|
/// DECLARATIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef ABC_USE_CUDD
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// FUNCTION DEFINITIONS ///
|
/// FUNCTION DEFINITIONS ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -266,15 +264,17 @@ void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2,
|
||||||
SeeAlso []
|
SeeAlso []
|
||||||
|
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
int Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh )
|
word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose )
|
||||||
{
|
{
|
||||||
int i, k, Id, nUsed = 0, nGood = 0;
|
Gia_Obj_t * pObj;
|
||||||
|
int i, k, nUsed = 0, nGood = 0;
|
||||||
int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
|
int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
|
||||||
int nMints = 1 << Vec_IntSize(vSupp);
|
int nMints = 1 << Vec_IntSize(vSupp);
|
||||||
word ** pSims = ABC_ALLOC( word *, Vec_IntSize(vSupp) );
|
word ** pSims = ABC_ALLOC( word *, Vec_IntSize(vSupp) );
|
||||||
|
word * pRes = ABC_CALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
|
||||||
int * pCounts = ABC_CALLOC( int, nMints );
|
int * pCounts = ABC_CALLOC( int, nMints );
|
||||||
Vec_IntForEachEntry( vSupp, Id, i )
|
Gia_ManForEachObjVec( vSupp, p, pObj, i )
|
||||||
pSims[i] = Vec_WrdEntryP( vSimI, Id * nWords );
|
pSims[i] = Vec_WrdEntryP( vSimI, Gia_ObjCioId(pObj) * nWords );
|
||||||
for ( k = 0; k < 64*nWords; k++ )
|
for ( k = 0; k < 64*nWords; k++ )
|
||||||
{
|
{
|
||||||
int iMint = 0;
|
int iMint = 0;
|
||||||
|
|
@ -288,13 +288,16 @@ int Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, i
|
||||||
{
|
{
|
||||||
nUsed += (pCounts[k] > 0);
|
nUsed += (pCounts[k] > 0);
|
||||||
nGood += (pCounts[k] > Thresh);
|
nGood += (pCounts[k] > Thresh);
|
||||||
|
if ( pCounts[k] > Thresh )
|
||||||
|
Abc_TtXorBit( pRes, k );
|
||||||
//printf( "%d ", pCounts[k] );
|
//printf( "%d ", pCounts[k] );
|
||||||
}
|
}
|
||||||
//printf( "\n" );
|
//printf( "\n" );
|
||||||
printf( "Total used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints );
|
if ( fVerbose )
|
||||||
|
printf( "Used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints );
|
||||||
ABC_FREE( pSims );
|
ABC_FREE( pSims );
|
||||||
ABC_FREE( pCounts );
|
ABC_FREE( pCounts );
|
||||||
return nUsed;
|
return pRes;
|
||||||
}
|
}
|
||||||
void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
|
void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
|
||||||
{
|
{
|
||||||
|
|
@ -305,7 +308,8 @@ void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
|
||||||
pObj = Gia_ManObj( p, iObj );
|
pObj = Gia_ManObj( p, iObj );
|
||||||
if ( Gia_ObjIsCi(pObj) )
|
if ( Gia_ObjIsCi(pObj) )
|
||||||
{
|
{
|
||||||
Vec_IntPush( vSupp, Gia_ObjCioId(pObj) );
|
//Vec_IntPush( vSupp, Gia_ObjCioId(pObj) );
|
||||||
|
Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert( Gia_ObjIsAnd(pObj) );
|
assert( Gia_ObjIsAnd(pObj) );
|
||||||
|
|
@ -320,24 +324,73 @@ Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts )
|
||||||
Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp );
|
Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp );
|
||||||
return vSupp;
|
return vSupp;
|
||||||
}
|
}
|
||||||
void Gia_ManSimInfoSynthOne( Gia_Man_t * p, Vec_Wrd_t * vSimI, int iOut, int nOuts, int Thresh )
|
Gia_Man_t * Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int LutSize, int Thresh, int fVerbose )
|
||||||
{
|
{
|
||||||
Vec_Int_t * vSupp = Gia_ManCollectSupp( p, iOut, nOuts );
|
extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
|
||||||
printf( "Group %3d / %3d / %3d : Supp = %3d ", iOut, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp) );
|
Gia_Man_t * pNew; Gia_Obj_t * pObj;
|
||||||
Gia_ManCountFraction( p, vSimI, vSupp, Thresh );
|
Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 18 );
|
||||||
Vec_IntFree( vSupp );
|
Vec_Int_t * vLeaves = Vec_IntAlloc( nIns );
|
||||||
}
|
Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, 1 ) : NULL;
|
||||||
void Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int GroupSize, int Thresh )
|
word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) );
|
||||||
{
|
word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k;
|
||||||
Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, 1 );
|
if ( vSimI )
|
||||||
int g, nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
|
{
|
||||||
|
int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
|
||||||
printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
|
printf( "Density of input patterns %6.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
|
||||||
printf( "The number of patterns %d with threshold %d (%6.2f %%).\n", nPats, Thresh, 100.0*Thresh/nPats );
|
printf( "The number of patterns %d with threshold %d (%6.2f %%).\n", nPats, Thresh, 100.0*Thresh/nPats );
|
||||||
for ( g = 0; g < Gia_ManCoNum(p); g += GroupSize )
|
}
|
||||||
Gia_ManSimInfoSynthOne( p, vSimI, g, GroupSize, Thresh );
|
Gia_ManFillValue( p );
|
||||||
Vec_WrdFree( vSimI );
|
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||||
|
pNew->pName = Abc_UtilStrsav( p->pName );
|
||||||
|
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
||||||
|
Gia_ManConst0(p)->Value = 0;
|
||||||
|
Gia_ManForEachCi( p, pObj, k )
|
||||||
|
pObj->Value = Gia_ManAppendCi(pNew);
|
||||||
|
Gia_ObjComputeTruthTableStart( p, nIns );
|
||||||
|
Gia_ManHashStart( pNew );
|
||||||
|
for ( g = 0; g < Gia_ManCoNum(p); g += nOuts )
|
||||||
|
{
|
||||||
|
Vec_Int_t * vSupp = Gia_ManCollectSupp( p, g, nOuts );
|
||||||
|
int Temp = fVerbose ? printf( "Group %3d / %3d / %3d : Supp = %3d %s", g, nOuts, Gia_ManCoNum(p), Vec_IntSize(vSupp), vSimI ? "":"\n" ) : 0;
|
||||||
|
word * pCare = vSimI ? Gia_ManCountFraction( p, vSimI, vSupp, Thresh, fVerbose ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
|
||||||
|
int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) );
|
||||||
|
assert( Vec_IntSize(vSupp) <= nIns );
|
||||||
|
Vec_IntClear( vLeaves );
|
||||||
|
Gia_ManForEachObjVec( vSupp, p, pObj, k )
|
||||||
|
Vec_IntPush( vLeaves, pObj->Value );
|
||||||
|
for ( k = 0; k < nOuts; k++ )
|
||||||
|
{
|
||||||
|
Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
|
||||||
|
if ( Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) )
|
||||||
|
{
|
||||||
|
word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
|
||||||
|
Abc_TtSharp( pTruth0, pCare, pTruth, nWords );
|
||||||
|
Abc_TtAnd( pTruth1, pCare, pTruth, nWords, 0 );
|
||||||
|
pObj->Value = Kit_TruthToGia2( pNew, (unsigned *)pTruth0, (unsigned *)pTruth1, Vec_IntSize(vLeaves), vMemory, vLeaves, 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pObj->Value = Gia_ObjFanin0(pObj)->Value;
|
||||||
|
pObj->Value ^= Gia_ObjFaninC0(pObj);
|
||||||
|
}
|
||||||
|
ABC_FREE( pCare );
|
||||||
|
Vec_IntFree( vSupp );
|
||||||
|
Temp = 0;
|
||||||
|
}
|
||||||
|
Gia_ManHashStop( pNew );
|
||||||
|
Gia_ManForEachCo( p, pObj, k )
|
||||||
|
pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
|
||||||
|
Gia_ObjComputeTruthTableStop( p );
|
||||||
|
ABC_FREE( pTruth0 );
|
||||||
|
ABC_FREE( pTruth1 );
|
||||||
|
Vec_IntFree( vLeaves );
|
||||||
|
Vec_IntFree( vMemory );
|
||||||
|
Vec_WrdFreeP( &vSimI );
|
||||||
|
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||||
|
return pNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ABC_USE_CUDD
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
||||||
Synopsis []
|
Synopsis []
|
||||||
|
|
|
||||||
|
|
@ -40836,16 +40836,34 @@ usage:
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
int Abc_CommandAbc9MinLut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
int Abc_CommandAbc9MinLut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
{
|
{
|
||||||
extern void Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int GroupSize, int Thresh );
|
extern Gia_Man_t * Gia_ManSimInfoSynth( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int LutSize, int Thresh, int fVerbose );
|
||||||
//extern Gia_Man_t * Gia_ManPerformMinLut( Gia_Man_t * p, int GroupSize, int LutSize, int fVerbose );
|
//extern Gia_Man_t * Gia_ManPerformMinLut( Gia_Man_t * p, int GroupSize, int LutSize, int fVerbose );
|
||||||
//Gia_Man_t * pTemp;
|
Gia_Man_t * pTemp;
|
||||||
char * pFileName = NULL;
|
char * pFileName = NULL;
|
||||||
int c, LutSize = 6, GroupSize = 3, Limit = 0, fVerbose = 0;
|
int c, nIns = 6, nOuts = 2, LutSize = 6, Limit = -1, fVerbose = 0;
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
while ( ( c = Extra_UtilGetopt( argc, argv, "KGLvh" ) ) != EOF )
|
while ( ( c = Extra_UtilGetopt( argc, argv, "IOKLvh" ) ) != EOF )
|
||||||
{
|
{
|
||||||
switch ( c )
|
switch ( c )
|
||||||
{
|
{
|
||||||
|
case 'I':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-I\" should be followed by a positive integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
nIns = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-O\" should be followed by a positive integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
nOuts = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
break;
|
||||||
case 'K':
|
case 'K':
|
||||||
if ( globalUtilOptind >= argc )
|
if ( globalUtilOptind >= argc )
|
||||||
{
|
{
|
||||||
|
|
@ -40855,15 +40873,6 @@ int Abc_CommandAbc9MinLut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
LutSize = atoi(argv[globalUtilOptind]);
|
LutSize = atoi(argv[globalUtilOptind]);
|
||||||
globalUtilOptind++;
|
globalUtilOptind++;
|
||||||
break;
|
break;
|
||||||
case 'G':
|
|
||||||
if ( globalUtilOptind >= argc )
|
|
||||||
{
|
|
||||||
Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" );
|
|
||||||
goto usage;
|
|
||||||
}
|
|
||||||
GroupSize = atoi(argv[globalUtilOptind]);
|
|
||||||
globalUtilOptind++;
|
|
||||||
break;
|
|
||||||
case 'L':
|
case 'L':
|
||||||
if ( globalUtilOptind >= argc )
|
if ( globalUtilOptind >= argc )
|
||||||
{
|
{
|
||||||
|
|
@ -40899,15 +40908,17 @@ int Abc_CommandAbc9MinLut( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
}
|
}
|
||||||
//pTemp = Gia_ManPerformMinLut( pAbc->pGia, GroupSize, LutSize, fVerbose );
|
//pTemp = Gia_ManPerformMinLut( pAbc->pGia, GroupSize, LutSize, fVerbose );
|
||||||
//Abc_FrameUpdateGia( pAbc, pTemp );
|
//Abc_FrameUpdateGia( pAbc, pTemp );
|
||||||
Gia_ManSimInfoSynth( pAbc->pGia, pFileName, GroupSize, Limit );
|
pTemp = Gia_ManSimInfoSynth( pAbc->pGia, pFileName, nIns, nOuts, LutSize, Limit, fVerbose );
|
||||||
|
Abc_FrameUpdateGia( pAbc, pTemp );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
Abc_Print( -2, "usage: &minlut [-KGL num] [-vh] <file>\n" );
|
Abc_Print( -2, "usage: &minlut [-IOKL num] [-vh] <file>\n" );
|
||||||
Abc_Print( -2, "\t performs specialized LUT mapping\n" );
|
Abc_Print( -2, "\t performs specialized LUT mapping\n" );
|
||||||
|
Abc_Print( -2, "\t-I num : the input support size [default = %d]\n", nIns );
|
||||||
|
Abc_Print( -2, "\t-O num : the output group size [default = %d]\n", nOuts );
|
||||||
Abc_Print( -2, "\t-K num : the LUT size for mapping [default = %d]\n", LutSize );
|
Abc_Print( -2, "\t-K num : the LUT size for mapping [default = %d]\n", LutSize );
|
||||||
Abc_Print( -2, "\t-G num : the output group size [default = %d]\n", GroupSize );
|
Abc_Print( -2, "\t-L num : patterns count after this limit [default = %d]\n", Limit );
|
||||||
Abc_Print( -2, "\t-L num : the limit when patterns count [default = %d]\n", Limit );
|
|
||||||
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-h : prints the command usage\n");
|
Abc_Print( -2, "\t-h : prints the command usage\n");
|
||||||
Abc_Print( -2, "\t<file> : file name with simulation information\n");
|
Abc_Print( -2, "\t<file> : file name with simulation information\n");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue