mirror of https://github.com/YosysHQ/abc.git
Updating &funtrace to trace function of the primary outputs of the AIG.
This commit is contained in:
parent
5d6a568c9e
commit
03d92930fa
|
|
@ -30,7 +30,7 @@ ABC_NAMESPACE_IMPL_START
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define GIA_MAX_CUTSIZE 8
|
||||
#define GIA_MAX_CUTNUM 65
|
||||
#define GIA_MAX_CUTNUM 257
|
||||
#define GIA_MAX_TT_WORDS ((GIA_MAX_CUTSIZE > 6) ? 1 << (GIA_MAX_CUTSIZE-6) : 1)
|
||||
|
||||
#define GIA_CUT_NO_LEAF 0xF
|
||||
|
|
@ -1116,6 +1116,39 @@ Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nC
|
|||
}
|
||||
return vRes;
|
||||
}
|
||||
Vec_Ptr_t * Gia_ManMatchCutsMany( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, int nFuncs, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
|
||||
{
|
||||
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fVerbose );
|
||||
Vec_Int_t * vLevel; int i, j, k, * pCut;
|
||||
abctime clkStart = Abc_Clock();
|
||||
assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) );
|
||||
Vec_Ptr_t * vRes = Vec_PtrAlloc( nFuncs );
|
||||
for ( i = 0; i < nFuncs; i++ )
|
||||
Vec_PtrPush( vRes, Vec_WecAlloc(10) );
|
||||
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
|
||||
{
|
||||
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
|
||||
{
|
||||
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
|
||||
assert( (pTruth[0] & 1) == 0 );
|
||||
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
|
||||
if ( *pSpot == -1 )
|
||||
continue;
|
||||
int iFunc = vMap ? Vec_IntEntry( vMap, *pSpot ) : 0;
|
||||
assert( iFunc < nFuncs );
|
||||
Vec_Wec_t * vCuts = (Vec_Wec_t *)Vec_PtrEntry( vRes, iFunc );
|
||||
vLevel = Vec_WecPushLevel( vCuts );
|
||||
Vec_IntPush( vLevel, i );
|
||||
for ( j = 1; j <= pCut[0]; j++ )
|
||||
Vec_IntPush( vLevel, pCut[j] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
Gia_StoFree( p );
|
||||
if ( fVerbose )
|
||||
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
|
||||
return vRes;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -1239,6 +1272,96 @@ void Gia_ManMatchCones( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutSize, int
|
|||
Abc_PrintTime( 1, "Total computation time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Function enumeration.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManMatchConesMinimizeTts( Vec_Wrd_t * vSims, int nVarsMax )
|
||||
{
|
||||
int nVars = 0;
|
||||
int nWordsMax = Abc_Truth6WordNum( nVarsMax ), nWords;
|
||||
int i, k = 0, nTruths = Vec_WrdSize(vSims) / nWordsMax;
|
||||
assert( nTruths * nWordsMax == Vec_WrdSize(vSims) );
|
||||
// support-minimize and find the largest supp size
|
||||
for ( i = 0; i < nTruths; i++ ) {
|
||||
word * pTruth = Vec_WrdEntryP( vSims, i * nWordsMax );
|
||||
int nVarsCur = Abc_TtMinBase( pTruth, NULL, nVarsMax, nVarsMax );
|
||||
nVars = Abc_MaxInt( nVars, nVarsCur );
|
||||
}
|
||||
// remap truth tables
|
||||
nWords = Abc_Truth6WordNum( nVars );
|
||||
for ( i = 0; i < nTruths; i++ ) {
|
||||
word * pTruth = Vec_WrdEntryP( vSims, i * nWordsMax );
|
||||
word * pTruth2 = Vec_WrdEntryP( vSims, k * nWords );
|
||||
if ( Abc_TtSupportSize(pTruth, nVars) < 3 )
|
||||
continue;
|
||||
memmove( pTruth2, pTruth, nWords * sizeof(word) );
|
||||
k++;
|
||||
if ( 0 ) {
|
||||
extern void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars );
|
||||
printf( "Type%d : ", i );
|
||||
Extra_PrintHexadecimal( stdout, (unsigned *)pTruth2, nVars );
|
||||
printf( "\n" );
|
||||
}
|
||||
}
|
||||
Vec_WrdShrink ( vSims, k * nWords );
|
||||
return nVars;
|
||||
}
|
||||
void Gia_ManMatchConesOutputPrint( Vec_Ptr_t * p, int fVerbose )
|
||||
{
|
||||
Vec_Wec_t * vCuts; int i;
|
||||
printf( "Nodes with matching cuts:\n" );
|
||||
Vec_PtrForEachEntry( Vec_Wec_t *, p, vCuts, i ) {
|
||||
if ( fVerbose ) {
|
||||
printf( "Type %d:\n", i );
|
||||
Vec_WecPrint( vCuts, 0 );
|
||||
}
|
||||
else
|
||||
printf( "Type %d present in %d cuts\n", i, Vec_WecSize(vCuts) );
|
||||
}
|
||||
}
|
||||
void Gia_ManMatchConesOutputFree( Vec_Ptr_t * p )
|
||||
{
|
||||
Vec_Wec_t * vCuts; int i;
|
||||
Vec_PtrForEachEntry( Vec_Wec_t *, p, vCuts, i )
|
||||
Vec_WecFree( vCuts );
|
||||
Vec_PtrFree( p );
|
||||
}
|
||||
void Gia_ManMatchConesOutput( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutNum, int fVerbose )
|
||||
{
|
||||
abctime clkStart = Abc_Clock();
|
||||
extern Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int_t ** pvMap, int fVerbose );
|
||||
Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(pSmall) );
|
||||
Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pSmall, vSimsPi, 1 );
|
||||
int nVars = Gia_ManMatchConesMinimizeTts( vSims, Gia_ManCiNum(pSmall) );
|
||||
Vec_WrdFree( vSimsPi );
|
||||
if ( nVars > 10 ) {
|
||||
printf( "Some output functions have support size more than 10.\n" );
|
||||
Vec_WrdFree( vSims );
|
||||
return;
|
||||
}
|
||||
Vec_Int_t * vMap = NULL;
|
||||
Vec_Mem_t * vTtMem = Dau_CollectNpnFunctionsArray( vSims, nVars, &vMap, fVerbose );
|
||||
int nFuncs = Vec_WrdSize(vSims) / Abc_Truth6WordNum(nVars);
|
||||
assert( Vec_WrdSize(vSims) == nFuncs * Abc_Truth6WordNum(nVars) );
|
||||
Vec_WrdFree( vSims );
|
||||
printf( "Using %d output functions with the support size between 3 and %d.\n", nFuncs, nVars );
|
||||
Vec_Ptr_t * vRes = Gia_ManMatchCutsMany( vTtMem, vMap, nFuncs, pBig, nVars, nCutNum, fVerbose );
|
||||
Vec_MemHashFree( vTtMem );
|
||||
Vec_MemFree( vTtMem );
|
||||
Vec_IntFree( vMap );
|
||||
Gia_ManMatchConesOutputPrint( vRes, fVerbose );
|
||||
Gia_ManMatchConesOutputFree( vRes );
|
||||
Abc_PrintTime( 1, "Total computation time", Abc_Clock() - clkStart );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -54369,10 +54369,10 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
{
|
||||
extern Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose );
|
||||
extern void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose );
|
||||
int c, nVars, nVars2, nCutNum = 8, nCutSize = 0, nNumFuncs = 5, nNumCones = 3, fVerbose = 0; word * pTruth = NULL;
|
||||
int c, nVars, nVars2, nCutNum = 8, nCutSize = 0, nNumFuncs = 5, nNumCones = 3, fOutputs = 0, fVerbose = 0; word * pTruth = NULL;
|
||||
char * pStr = NULL; Vec_Mem_t * vTtMem = NULL; Gia_Man_t * pTemp;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CKNMvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CKNMovh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -54420,6 +54420,9 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nNumCones < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'o':
|
||||
fOutputs ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -54442,16 +54445,27 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( strstr(argv[globalUtilOptind], ".aig") )
|
||||
{ // the entry on the command line is an AIGER file
|
||||
extern void Gia_ManMatchCones( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutSize, int nCutNum, int nNumFuncs, int nNumCones, int fVerbose );
|
||||
if ( nCutSize == 0 ) {
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): The LUT size for profiling should be given on the command line.\n" );
|
||||
return 0;
|
||||
}
|
||||
extern void Gia_ManMatchConesOutput( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutNum, int fVerbose );
|
||||
pTemp = Gia_AigerRead( argv[globalUtilOptind], 0, 0, 0 );
|
||||
if ( pTemp == NULL ) {
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): Cannot read input AIG \"%s\".\n", argv[globalUtilOptind] );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManMatchCones( pAbc->pGia, pTemp, nCutSize, nCutNum, nNumFuncs, nNumCones, fVerbose );
|
||||
if ( fOutputs ) {
|
||||
if ( Gia_ManCiNum(pTemp) > 16 ) {
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): The AIG \"%s\" has more than 16 primary inputs.\n", argv[globalUtilOptind] );
|
||||
Gia_ManStop( pTemp );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManMatchConesOutput( pAbc->pGia, pTemp, nCutNum, fVerbose );
|
||||
}
|
||||
else {
|
||||
if ( nCutSize == 0 ) {
|
||||
Abc_Print( -1, "Abc_CommandAbc9FunTrace(): The LUT size for profiling should be given on the command line.\n" );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManMatchCones( pAbc->pGia, pTemp, nCutSize, nCutNum, nNumFuncs, nNumCones, fVerbose );
|
||||
}
|
||||
Gia_ManStop( pTemp );
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -54480,12 +54494,13 @@ int Abc_CommandAbc9FunTrace( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &funtrace [-CKNM num] [-vh] {<truth> or <file.aig>}\n" );
|
||||
Abc_Print( -2, "usage: &funtrace [-CKNM num] [-ovh] {<truth> or <file.aig>}\n" );
|
||||
Abc_Print( -2, "\t traces the presence of the function in the current AIG\n" );
|
||||
Abc_Print( -2, "\t-C num : the number of cuts to compute at each node [default = %d]\n", nCutNum );
|
||||
Abc_Print( -2, "\t-K num : the LUT size to use when <file.aig> is given [default = %d]\n", nCutSize );
|
||||
Abc_Print( -2, "\t-N num : the number of functions to use when <file.aig> is given [default = %d]\n", nNumFuncs );
|
||||
Abc_Print( -2, "\t-M num : the number of logic cones to use when <file.aig> is given [default = %d]\n", nNumCones );
|
||||
Abc_Print( -2, "\t-o : toggles using AIG output functions instead of frequent cut functions [default = %s]\n", fOutputs ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
Abc_Print( -2, "\t<truth> : truth table in the hexadecimal notation used for tracing\n");
|
||||
|
|
|
|||
|
|
@ -872,6 +872,7 @@ Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose )
|
|||
***********************************************************************/
|
||||
Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int_t ** pvMap, int fVerbose )
|
||||
{
|
||||
assert( nVars <= 10 );
|
||||
abctime clkStart = Abc_Clock();
|
||||
Vec_Int_t * vMap = Vec_IntAlloc( 100 );
|
||||
Vec_Int_t * vCnts = Vec_IntAlloc( Vec_WrdSize(vFuncs) );
|
||||
|
|
@ -881,13 +882,15 @@ Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int
|
|||
int nMints = 1 << nVars;
|
||||
int * pPerm = Extra_PermSchedule( nVars );
|
||||
int * pComp = Extra_GreyCodeSchedule( nVars );
|
||||
int m, i, k, t, Entry; word Truth;
|
||||
assert( nWords == 1 );
|
||||
Vec_WrdForEachEntry( vFuncs, Truth, t )
|
||||
int m, i, k, t, Entry;
|
||||
word * pCopy = ABC_ALLOC( word, nWords );
|
||||
int nClasses = Vec_WrdSize(vFuncs) / nWords;
|
||||
assert( nClasses * nWords == Vec_WrdSize(vFuncs) );
|
||||
for ( t = 0; t < nClasses; t++ )
|
||||
{
|
||||
word * pTruth = Vec_WrdEntryP( vFuncs, nWords * t );
|
||||
int nFuncs = Vec_MemEntryNum(vTtMem);
|
||||
Truth = (Truth & 1) ? ~Truth : Truth;
|
||||
word pCopy[1] = {Truth};
|
||||
Abc_TtCopy( pCopy, pTruth, nWords, pTruth[0] & 1 );
|
||||
Vec_MemHashInsert( vTtMem, pCopy );
|
||||
for ( m = 0; m < nMints; m++ ) {
|
||||
Abc_TtFlip( pCopy, nWords, pComp[m] );
|
||||
|
|
@ -900,8 +903,12 @@ Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int
|
|||
else
|
||||
Vec_MemHashInsert( vTtMem, pCopy );
|
||||
}
|
||||
assert( Abc_TtEqual(pCopy, &Truth, nWords) );
|
||||
for ( i = 0; i < nFuncs; i++ ) {
|
||||
if ( pTruth[0] & 1 )
|
||||
assert( Abc_TtOpposite(pCopy, pTruth, nWords) );
|
||||
else
|
||||
assert( Abc_TtEqual(pCopy, pTruth, nWords) );
|
||||
int nFuncs2 = Vec_MemEntryNum(vTtMem);
|
||||
for ( i = nFuncs; i < nFuncs2; i++ ) {
|
||||
Abc_TtCopy( pCopy, Vec_MemReadEntry(vTtMem, i), nWords, 0 );
|
||||
for ( k = 0; k < nPerms; k++ ) {
|
||||
Abc_TtSwapAdjacent( pCopy, nWords, pPerm[k] );
|
||||
|
|
@ -914,13 +921,15 @@ Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int
|
|||
Vec_IntPush( vMap, t );
|
||||
Vec_IntPush( vCnts, Vec_MemEntryNum(vTtMem) - nFuncs );
|
||||
}
|
||||
ABC_FREE( pCopy );
|
||||
ABC_FREE( pPerm );
|
||||
ABC_FREE( pComp );
|
||||
if ( fVerbose ) {
|
||||
int Lim = Abc_MinInt( Vec_IntSize(vCnts), 7 );
|
||||
printf( "Collected %d", Vec_MemEntryNum(vTtMem) );
|
||||
Vec_IntForEachEntryStop( vCnts, Entry, i, 7 )
|
||||
Vec_IntForEachEntryStop( vCnts, Entry, i, Lim )
|
||||
printf( " %c %d", i ? '+' : '=', Entry );
|
||||
if ( Vec_IntSize(vCnts) > 7 )
|
||||
if ( Vec_IntSize(vCnts) > Lim )
|
||||
printf( " + ..." );
|
||||
printf( " NPN class members. " );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
|
||||
|
|
|
|||
Loading…
Reference in New Issue