summaryrefslogtreecommitdiffstats
path: root/src/aig/gia/giaMinLut.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/gia/giaMinLut.c')
-rw-r--r--src/aig/gia/giaMinLut.c1058
1 files changed, 1058 insertions, 0 deletions
diff --git a/src/aig/gia/giaMinLut.c b/src/aig/gia/giaMinLut.c
new file mode 100644
index 00000000..5304486d
--- /dev/null
+++ b/src/aig/gia/giaMinLut.c
@@ -0,0 +1,1058 @@
+/**CFile****************************************************************
+
+ FileName [giaMinLut.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Scalable AIG package.]
+
+ Synopsis [Collapsing AIG.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: giaMinLut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "giaAig.h"
+#include "base/main/mainInt.h"
+#include "opt/sfm/sfm.h"
+
+#ifdef ABC_USE_CUDD
+#include "bdd/extrab/extraBdd.h"
+#include "bdd/dsd/dsd.h"
+#endif
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Vec_WrdReadLayerText( char * pFileName, int * pnIns, int * pnOuts )
+{
+ char * pThis, pLine[1000];
+ Vec_Wec_t * vRes; int iLine;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ vRes = Vec_WecAlloc(100);
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ if ( iLine == 0 )
+ {
+ pThis = strstr( pLine, "[" );
+ *pnIns = atoi( pThis+1 ) + 1;
+ pThis = strstr( pThis+1, "[" );
+ *pnOuts = atoi( pThis+1 ) + 1;
+ }
+ else
+ {
+ Vec_Int_t * vLevel = NULL;
+ for ( pThis = pLine; (pThis = strstr(pThis, "M0[")); pThis++ )
+ {
+ if ( vLevel == NULL )
+ vLevel = Vec_WecPushLevel( vRes );
+ Vec_IntPush( vLevel, atoi( pThis+3 ) );
+ }
+ if ( vLevel )
+ Vec_IntReverseOrder( vLevel );
+ }
+ }
+ fclose( pFile );
+ //Vec_WecPrint( vRes, 0 );
+ return vRes;
+}
+int Vec_WrdReadTruthTextOne( char * pFileName, int nIns, int nOuts, word * pRes )
+{
+ int i, nWords = Abc_TtWordNum( nIns );
+ char * pStart, * pBuffer = Extra_FileReadContents( pFileName );
+ if ( pBuffer == NULL )
+ {
+ printf( "Cannot read file \"%s\".\n", pFileName );
+ return 0;
+ }
+ pStart = pBuffer;
+ for ( i = 0; i < nOuts; i++ )
+ {
+ pStart = strstr( pStart + 1, "0x" );
+ if ( !Extra_ReadHex( (unsigned *)(pRes + i*nWords), pStart + 2, nWords*16 ) )
+ {
+ printf( "Cannot read truth table %d (out of %d) in file \"%s\".\n", i, nOuts, pFileName );
+ ABC_FREE( pBuffer );
+ return 0;
+ }
+ }
+ ABC_FREE( pBuffer );
+ return 1;
+}
+word * Vec_WrdReadTruthText( char * pFileName, int nIns, int nOuts, int nFiles )
+{
+ char FileName[1000];
+ int i, nWords = Abc_TtWordNum( nIns );
+ word * pRes = ABC_CALLOC( word, nOuts*nFiles*nWords );
+ for ( i = 0; i < nFiles; i++ )
+ {
+ assert( strlen(pFileName) < 900 );
+ strcpy( FileName, pFileName );
+ sprintf( FileName + strlen(FileName) - 2, "_N%d.bench", i );
+ if ( !Vec_WrdReadTruthTextOne( FileName, nIns, nOuts, pRes + i*nOuts*nWords ) )
+ {
+ ABC_FREE( pRes );
+ return NULL;
+ }
+ }
+ return pRes;
+}
+Gia_Man_t * Vec_WrdReadTest( char * pFileName )
+{
+ extern int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj );
+ extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ Gia_Man_t * pPart, * pNew = NULL; Gia_Obj_t * pObj;
+ int i, k, nIns, nOuts, iLit;
+ Vec_Wec_t * vRes = Vec_WrdReadLayerText( pFileName, &nIns, &nOuts );
+ int nBitsI = vRes ? Vec_WecMaxLevelSize(vRes) : 0;
+ int nBitsO = vRes ? nOuts / Vec_WecSize(vRes) : 0;
+ int nWords = Abc_TtWordNum(nBitsI);
+ word * pFuncs = vRes ? Vec_WrdReadTruthText( pFileName, nBitsI, nBitsO, Vec_WecSize(vRes) ) : NULL;
+ Vec_Int_t * vPart, * vLits = Vec_IntAlloc( nOuts );
+ if ( vRes == NULL || pFuncs == NULL )
+ {
+ Vec_WecFreeP( &vRes );
+ Vec_IntFreeP( &vLits );
+ ABC_FREE( pFuncs );
+ return NULL;
+ }
+ assert( nOuts % Vec_WecSize(vRes) == 0 );
+ pNew = Gia_ManStart( 10000 );
+ pNew->pName = Abc_UtilStrsav( pFileName );
+ pNew->pSpec = NULL;
+ for ( i = 0; i < nIns; i++ )
+ Gia_ManAppendCi(pNew);
+ Gia_ManHashStart( pNew );
+ Vec_WecForEachLevel( vRes, vPart, i )
+ {
+ assert( Vec_IntSize(vPart) <= nBitsI );
+ pPart = Gia_TryPermOptCare( pFuncs + i * nBitsO * nWords, nBitsI, nBitsO, nWords, 20, 0 );
+ Gia_ManFillValue( pPart );
+ Gia_ManConst0(pPart)->Value = 0;
+ Gia_ManForEachCi( pPart, pObj, k )
+ pObj->Value = Abc_Var2Lit( 1+Vec_IntEntry(vPart, k), 0 );
+ Gia_ManForEachCo( pPart, pObj, k )
+ {
+ Gia_ManPerformLNetOpt_rec( pNew, pPart, Gia_ObjFanin0(pObj) );
+ Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) );
+ }
+ Gia_ManStop( pPart );
+ }
+ Gia_ManHashStop( pNew );
+ Vec_IntForEachEntry( vLits, iLit, i )
+ Gia_ManAppendCo( pNew, iLit );
+ ABC_FREE( pFuncs );
+ Vec_WecFree( vRes );
+ Vec_IntFree( vLits );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO, int nIns, int nOuts )
+{
+ int i, nSize, iLine, nLines, nWords;
+ char pLine[1000];
+ Vec_Wrd_t * vSimI, * vSimO;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize % (nIns + nOuts + 1) > 0 )
+ {
+ printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + nOuts + 1) );
+ fclose( pFile );
+ return;
+ }
+ rewind( pFile );
+ nLines = nSize / (nIns + nOuts + 1);
+ nWords = (nLines + 63)/64;
+ vSimI = Vec_WrdStart( nIns *nWords );
+ vSimO = Vec_WrdStart( nOuts*nWords );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ for ( i = 0; i < nIns; i++ )
+ if ( pLine[nIns-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine );
+ else assert( pLine[nIns-1-i] == '0' );
+ for ( i = 0; i < nOuts; i++ )
+ if ( pLine[nIns+nOuts-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine );
+ else assert( pLine[nIns+nOuts-1-i] == '0' );
+ }
+ fclose( pFile );
+ *pvSimI = vSimI;
+ *pvSimO = vSimO;
+ printf( "Read %d words of simulation data for %d inputs and %d outputs (padded %d zero-patterns).\n", nWords, nIns, nOuts, nWords*64-nLines );
+}
+int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
+{
+ int i, nSize, iLine, nLines, nWords, nIns;
+ char pLine[1000];
+ Vec_Wrd_t * vSimI;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return 0;
+ }
+ if ( !fgets(pLine, 1000, pFile) || (nIns = strlen(pLine)-1) < 1 )
+ {
+ printf( "Cannot find the number of inputs in file \"%s\".\n", pFileName );
+ fclose( pFile );
+ return 0;
+ }
+ fseek( pFile, 0, SEEK_END );
+ nSize = ftell( pFile );
+ if ( nSize % (nIns + 1) > 0 )
+ {
+ printf( "Cannot read file with simulation data that is not aligned at 8 bytes (remainder = %d).\n", nSize % (nIns + 1) );
+ fclose( pFile );
+ return 0;
+ }
+ rewind( pFile );
+ nLines = nSize / (nIns + 1);
+ nWords = (nLines + 63)/64;
+ vSimI = Vec_WrdStart( nIns *nWords );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ {
+ for ( i = 0; i < nIns; i++ )
+ if ( pLine[nIns-1-i] == '1' )
+ Abc_TtXorBit( Vec_WrdArray(vSimI) + i*nWords, iLine );
+ else assert( pLine[nIns-1-i] == '0' );
+ }
+ fclose( pFile );
+ *pvSimI = vSimI;
+ printf( "Read %d words of simulation data for %d inputs (padded to 64-bit boundary with %d zero-patterns).\n", nWords, nIns, nWords*64-nLines );
+ return nIns;
+}
+Vec_Int_t * Vec_WrdReadNumsOut( char * pFileName, int fVerbose )
+{
+ char pLine[1000];
+ Vec_Int_t * vNums; int iLine;
+ FILE * pFile = fopen( pFileName, "rb" );
+ if ( pFile == NULL )
+ {
+ printf( "Cannot open file \"%s\" for reading.\n", pFileName );
+ return NULL;
+ }
+ vNums = Vec_IntAlloc( 1000 );
+ for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
+ Vec_IntPush( vNums, atoi(pLine) );
+ fclose( pFile );
+ if ( fVerbose )
+ printf( "Finished reading %d output values from file \"%s\".\n", Vec_IntSize(vNums), pFileName );
+ return vNums;
+}
+Vec_Wrd_t * Vec_WrdReadTextOut( char * pFileName, int nOuts )
+{
+ int i, iLine, nLines, nWords;
+ Vec_Wrd_t * vSimO;
+ Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName, 1 );
+ if ( vNums == NULL )
+ return NULL;
+ nLines = Vec_IntSize(vNums);
+ nWords = (nLines + 63)/64;
+ vSimO = Vec_WrdStart( nOuts*nWords );
+ Vec_IntForEachEntry( vNums, i, iLine )
+ Abc_TtXorBit( Vec_WrdArray(vSimO) + i*nWords, iLine );
+ Vec_IntFree( vNums );
+ printf( "Read %d words of simulation data for %d outputs (padded %d zero-patterns).\n", nWords, nOuts, nWords*64-nLines );
+ return vSimO;
+}
+void Gia_ManReadSimInfoInputs( char * pFileName, char * pFileOut1, int fVerbose )
+{
+ Vec_Wrd_t * vSimI;
+ Vec_WrdReadText2( pFileName, &vSimI );
+ Vec_WrdDumpBin( pFileOut1, vSimI, fVerbose );
+ Vec_WrdFree( vSimI );
+}
+void Gia_ManReadSimInfoOutputs( char * pFileName, char * pFileOut, int nOuts )
+{
+ Vec_Wrd_t * vSimO = Vec_WrdReadTextOut( pFileName, nOuts );
+ Vec_WrdDumpBin( pFileOut, vSimO, 1 );
+ Vec_WrdFree( vSimO );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wrd_t * Vec_WrdZoneExtract( int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords )
+{
+ int z, nZones = Vec_WrdSize(p)/ZoneSize;
+ int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord );
+ Vec_Wrd_t * pNew = Vec_WrdStart( nZones*nWords );
+ for ( z = 0; z < nZones; z++ )
+ for ( w = 0; w < Limit; w++ )
+ Vec_WrdWriteEntry( pNew, z*nWords + w, Vec_WrdEntry(p, z*ZoneSize + iWord + w) );
+ return pNew;
+}
+void Vec_WrdZoneInsert( Vec_Wrd_t * pNew, int ZoneSize, Vec_Wrd_t * p, int iWord, int nWords )
+{
+ int z, nZones = Vec_WrdSize(pNew)/ZoneSize;
+ int w, Limit = Abc_MinInt( nWords, ZoneSize-iWord );
+ for ( z = 0; z < nZones; z++ )
+ for ( w = 0; w < Limit; w++ )
+ Vec_WrdWriteEntry( pNew, z*ZoneSize + iWord + w, Vec_WrdEntry(p, z*nWords + w) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManSimInfoPrintOne( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsOut, int nWords, int nPats )
+{
+ int Id, i, k;
+ for ( k = 0; k < nPats; k++ )
+ {
+ Gia_ManForEachCiId( p, Id, i )
+ // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 );
+ printf( "%d", (int)(Vec_WrdEntry(vSimsIn, nWords*i) >> k) & 1 );
+ printf( " " );
+ Gia_ManForEachCoId( p, Id, i )
+ // printf( "%d", Vec_WrdEntry(p->vSims, p->nSimWords*Id) & 1 );
+ printf( "%d", (int)(Vec_WrdEntry(vSimsOut, nWords*i) >> k) & 1 );
+ printf( "\n" );
+ }
+}
+Vec_Wrd_t * Gia_ManSimInfoTryOne( Gia_Man_t * p, Vec_Wrd_t * vSimI, int fPrint )
+{
+ extern Vec_Wrd_t * Gia_ManSimulateWordsOut( Gia_Man_t * p, Vec_Wrd_t * vSimsIn );
+ Vec_Wrd_t * vSimsOut = Gia_ManSimulateWordsOut( p, vSimI );
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ assert( Vec_WrdSize(vSimI) % Gia_ManCiNum(p) == 0 );
+ if ( fPrint )
+ Gia_ManSimInfoPrintOne( p, vSimI, vSimsOut, nWords, 6 );
+ return vSimsOut;
+}
+int Gia_ManSimEvalOne( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ word * pSim0 = ABC_CALLOC( word, nWords );
+ assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords );
+ word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords );
+ Abc_TtOrXor( pSim0, pSimImpl, pSimGold, nWords );
+ }
+ Count = Abc_TtCountOnesVec( pSim0, nWords );
+ printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n",
+ Count, 100.0*Count/(64*nWords), 64*nWords, Abc_TtFindFirstBit2(pSim0, nWords) );
+ ABC_FREE( pSim0 );
+ return Count;
+}
+int Gia_ManSimEvalOne2( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int i, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ word * pSim0 = ABC_CALLOC( word, nWords );
+ assert( Vec_WrdSize(vSimO) == Vec_WrdSize(vSimO_new) );
+ for ( i = 0; i < Gia_ManCoNum(p); i++ )
+ {
+ word * pSimGold = Vec_WrdEntryP( vSimO, i * nWords );
+ word * pSimImpl = Vec_WrdEntryP( vSimO_new, i * nWords );
+ Abc_TtXor( pSim0, pSimImpl, pSimGold, nWords, 0 );
+ Count += Abc_TtCountOnesVec( pSim0, nWords );
+ }
+ printf( "Number of failed patterns is %d (%8.4f %% of %d). The first one is %d.\n",
+ Count, 100.0*Count/(64*nWords*Gia_ManCoNum(p)), 64*nWords*Gia_ManCoNum(p), Abc_TtFindFirstBit2(pSim0, nWords) );
+ ABC_FREE( pSim0 );
+ return Count;
+}
+int Gia_ManSimEvalMaxValue( Vec_Wrd_t * vSimO, int nWords, int nOuts, int nBits, int iPat )
+{
+ int o, ValueMax = -1, OutMax = -1;
+ for ( o = 0; o < nOuts; o++ )
+ {
+ int i, Value = 0;
+ for ( i = 0; i < nBits; i++ )
+ {
+ word * pSim = Vec_WrdEntryP( vSimO, (o*nBits+i) * nWords );
+ if ( Abc_TtGetBit(pSim, iPat) )
+ Value |= 1 << i;
+ }
+ if ( ValueMax <= Value )
+ {
+ ValueMax = Value;
+ OutMax = o;
+ }
+ }
+ return OutMax;
+}
+int Gia_ManSimEvalOne3( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Int_t * vValues, int nBits )
+{
+ int i, Value, nOuts = Gia_ManCoNum(p) / nBits;
+ int First = -1, Count = 0, nWords = Vec_WrdSize(vSimO) / Gia_ManCoNum(p);
+ assert( Gia_ManCoNum(p) % nBits == 0 );
+ assert( 64*(nWords-1) < Vec_IntSize(vValues) && Vec_IntSize(vValues) <= 64*nWords );
+ Vec_IntForEachEntry( vValues, Value, i )
+ if ( Value == Gia_ManSimEvalMaxValue(vSimO, nWords, nOuts, nBits, i) )
+ {
+ Count++;
+ if ( First == -1 )
+ First = i;
+ }
+ printf( "The accuracy is %8.4f %% (%d out of %d output are correct, for example, output number %d).\n",
+ 100.0*Count/Vec_IntSize(vValues), Count, Vec_IntSize(vValues), First );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f \n", 100.0*Count/Vec_IntSize(vValues) );
+ fclose( pTable );
+ }
+ return Count;
+}
+Vec_Wrd_t * Gia_ManSimInfoTry( Gia_Man_t * p, Vec_Wrd_t * vSimI )
+{
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ int w, nWordsOne = 200, nWordBatches = (nWords + nWordsOne - 1)/nWordsOne;
+ Vec_Wrd_t * vSimO_new = Vec_WrdStart( nWords * Gia_ManCoNum(p) );
+ for ( w = 0; w < nWordBatches; w++ )
+ {
+ //int Value = printf( "%3d / %3d : ", w, nWordBatches );
+ Vec_Wrd_t * vSimI_ = Vec_WrdZoneExtract( nWords, vSimI, w*nWordsOne, nWordsOne );
+ Vec_Wrd_t * vSimO_ = Gia_ManSimInfoTryOne( p, vSimI_, 0 );
+ Vec_WrdZoneInsert( vSimO_new, nWords, vSimO_, w*nWordsOne, nWordsOne );
+ Vec_WrdFree( vSimI_ );
+ Vec_WrdFree( vSimO_ );
+ //Value = 0;
+ }
+ return vSimO_new;
+}
+int Gia_ManSimInfoEval_old( Gia_Man_t * p, Vec_Wrd_t * vSimO, Vec_Wrd_t * vSimO_new )
+{
+ int nResult = Gia_ManSimEvalOne2(p, vSimO, vSimO_new);
+ //Vec_WrdDumpBin( "temp.simo", vSimO_new, 1 );
+ printf( "Total errors = %d. ", nResult );
+ printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO_new), Vec_WrdSize(vSimO_new))/(64*Vec_WrdSize(vSimO_new)) );
+ return nResult;
+}
+void Gia_ManSimInfoPassTest( Gia_Man_t * p, char * pFileName, char * pFileName2, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSimI = Vec_WrdReadBin( pFileName, fVerbose );
+ Vec_Wrd_t * vSimO = Gia_ManSimInfoTry( p, vSimI );
+ if ( fVerbose )
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ if ( fVerbose )
+ printf( "Density of output patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimO), Vec_WrdSize(vSimO))/(64*Vec_WrdSize(vSimO)) );
+ Vec_WrdDumpBin( pFileName2, vSimO, fVerbose );
+ Vec_WrdFree( vSimI );
+ Vec_WrdFree( vSimO );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+void Gia_ManSimInfoEval( Gia_Man_t * p, char * pFileName, char * pFileName2, int nOuts, int fVerbose )
+{
+ abctime clk = Abc_Clock();
+ Vec_Wrd_t * vSim1 = Vec_WrdReadBin( pFileName, fVerbose );
+ Vec_Int_t * vNums = Vec_WrdReadNumsOut( pFileName2, fVerbose );
+ assert( nOuts > 0 );
+ if ( fVerbose )
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSim1), Vec_WrdSize(vSim1))/(64*Vec_WrdSize(vSim1)) );
+ Gia_ManSimEvalOne3( p, vSim1, vNums, nOuts );
+ Vec_WrdFree( vSim1 );
+ Vec_IntFree( vNums );
+ if ( fVerbose )
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+word * Gia_ManCountFraction( Gia_Man_t * p, Vec_Wrd_t * vSimI, Vec_Int_t * vSupp, int Thresh, int fVerbose, int * pCare )
+{
+ Gia_Obj_t * pObj;
+ int i, k, nUsed = 0, nGood = 0;
+ int nWords = Vec_WrdSize(vSimI) / Gia_ManCiNum(p);
+ int nMints = 1 << 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 );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ pSims[i] = Vec_WrdEntryP( vSimI, Gia_ObjCioId(pObj) * nWords );
+ for ( k = 0; k < 64*nWords; k++ )
+ {
+ int iMint = 0;
+ for ( i = 0; i < Vec_IntSize(vSupp); i++ )
+ if ( Abc_TtGetBit(pSims[i], k) )
+ iMint |= 1 << i;
+ assert( iMint < nMints );
+ pCounts[iMint]++;
+ }
+ for ( k = 0; k < nMints; k++ )
+ {
+ nUsed += (pCounts[k] > 0);
+ nGood += (pCounts[k] >= Thresh);
+ if ( pCounts[k] >= Thresh )
+ Abc_TtXorBit( pRes, k );
+ //printf( "%d ", pCounts[k] );
+ }
+ if ( Vec_IntSize(vSupp) < 6 )
+ pRes[0] = Abc_Tt6Stretch( pRes[0], Vec_IntSize(vSupp) );
+ //printf( "\n" );
+ if ( fVerbose )
+ printf( "Used %4d and good %4d (out of %4d).\n", nUsed, nGood, nMints );
+ ABC_FREE( pSims );
+ ABC_FREE( pCounts );
+ *pCare = nGood;
+ return pRes;
+}
+void Gia_ManPermuteSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vLevels, Vec_Int_t * vCounts )
+{
+ Gia_Obj_t * pObj; int n;
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ return;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vLevels, vCounts );
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vLevels, vCounts );
+ for ( n = 0; n < 2; n++ )
+ {
+ Gia_Obj_t * pFanin = n ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj);
+ if ( !Gia_ObjIsCi(pFanin) )
+ continue;
+ Vec_IntAddToEntry( vLevels, Gia_ObjCioId(pFanin), Gia_ObjLevel(p, pObj) );
+ Vec_IntAddToEntry( vCounts, Gia_ObjCioId(pFanin), 1 );
+ }
+}
+void Gia_ManPermuteSupp( Gia_Man_t * p, int iOut, int nOuts, Vec_Int_t * vSupp )
+{
+ Vec_Int_t * vLevels = Vec_IntStart( Gia_ManCiNum(p) );
+ Vec_Int_t * vCounts = Vec_IntStart( Gia_ManCiNum(p) );
+ int i, * pCost = ABC_CALLOC( int, Gia_ManCiNum(p) );
+ Gia_Obj_t * pObj;
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManPermuteSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vLevels, vCounts );
+ Gia_ManForEachObjVec( vSupp, p, pObj, i )
+ pCost[i] = 10000 * Vec_IntEntry(vLevels, Gia_ObjCioId(pObj)) / Abc_MaxInt(1, Vec_IntEntry(vCounts, Gia_ObjCioId(pObj)));
+ Vec_IntFree( vCounts );
+ Vec_IntFree( vLevels );
+ Vec_IntSelectSortCost2( Vec_IntArray(vSupp), Vec_IntSize(vSupp), pCost );
+ assert( Vec_IntSize(vSupp) < 2 || pCost[0] <= pCost[1] );
+ ABC_FREE( pCost );
+}
+void Gia_ManCollectSupp_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vSupp )
+{
+ Gia_Obj_t * pObj;
+ if ( !iObj || Gia_ObjIsTravIdCurrentId(p, iObj) )
+ return;
+ Gia_ObjSetTravIdCurrentId(p, iObj);
+ pObj = Gia_ManObj( p, iObj );
+ if ( Gia_ObjIsCi(pObj) )
+ {
+ //Vec_IntPush( vSupp, Gia_ObjCioId(pObj) );
+ Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
+ return;
+ }
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0(pObj, iObj), vSupp );
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId1(pObj, iObj), vSupp );
+}
+Vec_Int_t * Gia_ManCollectSupp( Gia_Man_t * p, int iOut, int nOuts )
+{
+ Vec_Int_t * vSupp = Vec_IntAlloc( 16 ); int i;
+ Gia_ManIncrementTravId( p );
+ for ( i = 0; i < nOuts; i++ )
+ Gia_ManCollectSupp_rec( p, Gia_ObjFaninId0p(p, Gia_ManCo(p, iOut+i)), vSupp );
+ return vSupp;
+}
+Vec_Int_t * Gia_ManCollectSuppNew( Gia_Man_t * p, int iOut, int nOuts )
+{
+ Vec_Int_t * vRes = Gia_ManCollectSupp( p, iOut, nOuts );
+ Gia_ManPermuteSupp( p, iOut, nOuts, vRes );
+ return vRes;
+}
+int Gia_ManPerformLNetOpt_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj )
+{
+ if ( ~pObj->Value )
+ return pObj->Value;
+ assert( Gia_ObjIsAnd(pObj) );
+ Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin0(pObj) );
+ Gia_ManPerformLNetOpt_rec( pNew, p, Gia_ObjFanin1(pObj) );
+ return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+}
+Gia_Man_t * Gia_ManPerformLNetOpt( Gia_Man_t * p, int fTryNew, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOpt( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ extern Gia_Man_t * Gia_TryPermOptCare( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ extern int Kit_TruthToGia2( Gia_Man_t * p, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash );
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew; Gia_Obj_t * pObj;
+ Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 18 );
+ Vec_Int_t * vLeaves = Vec_IntAlloc( nIns );
+ Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL;
+ word * pTruth0 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) );
+ word * pTruth1 = ABC_CALLOC( word, Abc_Truth6WordNum(nIns) ); int g, k; float CareAve = 0;
+ word * pTruthsTry = ABC_CALLOC( word, 2*nOuts*Abc_Truth6WordNum(nIns) );
+ if ( vSimI && fVerbose )
+ {
+ //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ printf( "Using patterns with count %d and higher as cares.\n", Thresh );
+ }
+ Gia_ManLevelNum( p );
+ Gia_ManFillValue( p );
+ 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_ManCollectSuppNew( p, g, nOuts );
+ int Care = 1 << Vec_IntSize(vSupp), 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, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) );
+ CareAve += 100.0*Care/(1 << 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 );
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtSharp( pTruth0, pCare, pTruth, nWords );
+ Abc_TtAnd( pTruth1, pCare, pTruth, nWords, 0 );
+ if ( vSimI )
+ {
+ Abc_TtCopy( pTruthsTry + (2*k+0)*nWords, pTruth1, nWords, 0 );
+ Abc_TtCopy( pTruthsTry + (2*k+1)*nWords, pTruth0, nWords, 0 );
+ }
+ else
+ Abc_TtCopy( pTruthsTry + k*nWords, pTruth1, nWords, 0 );
+ if ( !fTryNew )
+ {
+ pObj->Value = Kit_TruthToGia2( pNew, (unsigned *)pTruth0, (unsigned *)pTruth1, Vec_IntSize(vLeaves), vMemory, vLeaves, 1 );
+ pObj->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ }
+ if ( fTryNew )
+ {
+ Gia_Man_t * pMin;
+ if ( vSimI )
+ pMin = Gia_TryPermOpt( pTruthsTry, Vec_IntSize(vSupp), 2*nOuts, nWords, nRounds, fVerbose );
+ else
+ pMin = Gia_TryPermOptCare( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose );
+ Gia_ManFillValue( pMin );
+ Gia_ManConst0(pMin)->Value = 0;
+ Gia_ManForEachCi( pMin, pObj, k )
+ pObj->Value = Vec_IntEntry( vLeaves, k );
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ Gia_Obj_t * pObj2 = Gia_ManCo( pMin, k );
+ pObj->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj2) );
+ pObj->Value ^= Gia_ObjFaninC0(pObj2);
+ pObj->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ Gia_ManStop( pMin );
+ }
+ ABC_FREE( pCare );
+ Vec_IntFree( vSupp );
+ Temp = 0;
+ }
+ CareAve /= Gia_ManCoNum(p)/nOuts;
+ 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) );
+ printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f ", CareAve );
+ fclose( pTable );
+ }
+ ABC_FREE( pTruthsTry );
+ return pNew;
+}
+Gia_Man_t * Gia_ManPerformLNetOptNew( Gia_Man_t * p, char * pFileName, int nIns, int nOuts, int Thresh, int nRounds, int fVerbose )
+{
+ extern Gia_Man_t * Gia_TryPermOptNew( word * pTruths, int nIns, int nOuts, int nWords, int nRounds, int fVerbose );
+ abctime clk = Abc_Clock();
+ Gia_Man_t * pNew, * pMin; Gia_Obj_t * pObj;
+ Vec_Int_t * vLeaves = Vec_IntAlloc( nIns );
+ Vec_Wrd_t * vSimI = pFileName ? Vec_WrdReadBin( pFileName, fVerbose ) : NULL;
+ word * pTruthsTry = ABC_CALLOC( word, (nOuts+1)*Abc_Truth6WordNum(nIns) );
+ int k, g; float CareAve = 0;
+ if ( vSimI && fVerbose )
+ {
+ //int nPats = 64*Vec_WrdSize(vSimI)/Gia_ManCiNum(p);
+ printf( "Density of input patterns %8.4f.\n", (float)Abc_TtCountOnesVec(Vec_WrdArray(vSimI), Vec_WrdSize(vSimI))/(64*Vec_WrdSize(vSimI)) );
+ printf( "Using patterns with count %d and higher as cares.\n", Thresh );
+ }
+ Gia_ManLevelNum( p );
+ Gia_ManFillValue( p );
+ 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 )
+ {
+ for ( k = 0; k < nOuts; k++ )
+ if ( Gia_ObjIsAnd(Gia_ObjFanin0(Gia_ManCo( p, g+k ))) )
+ break;
+ if ( k == nOuts )
+ {
+ for ( k = 0; k < nOuts; k++ )
+ {
+ Gia_Obj_t * pObj = Gia_ManCo( p, g+k );
+ pObj->Value = Gia_ObjFanin0Copy(pObj);
+ }
+ continue;
+ }
+ else
+ {
+
+ Vec_Int_t * vSupp = Gia_ManCollectSuppNew( p, g, nOuts );
+ int Care = 1 << Vec_IntSize(vSupp), 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, &Care ) : ABC_FALLOC( word, Abc_Truth6WordNum(Vec_IntSize(vSupp)) );
+ int nWords = Abc_Truth6WordNum( Vec_IntSize(vSupp) );
+ CareAve += 100.0*Care/(1 << 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 );
+ word * pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
+ Abc_TtCopy( pTruthsTry + k*nWords, pTruth, nWords, Gia_ObjFaninC0(pObj) );
+ }
+ Abc_TtCopy( pTruthsTry + nOuts*nWords, pCare, nWords, 0 );
+ ABC_FREE( pCare );
+ pMin = Gia_TryPermOptNew( pTruthsTry, Vec_IntSize(vSupp), nOuts, nWords, nRounds, fVerbose );
+ Gia_ManFillValue( pMin );
+ Gia_ManConst0(pMin)->Value = 0;
+ Gia_ManForEachCi( pMin, pObj, k )
+ pObj->Value = Vec_IntEntry( vLeaves, k );
+ Gia_ManForEachCo( pMin, pObj, k )
+ {
+ Gia_Obj_t * pObj0 = Gia_ManCo( p, g+k );
+ pObj0->Value = Gia_ManPerformLNetOpt_rec( pNew, pMin, Gia_ObjFanin0(pObj) );
+ pObj0->Value ^= Gia_ObjFaninC0(pObj);
+ }
+ Gia_ManStop( pMin );
+ Vec_IntFree( vSupp );
+ Temp = 0;
+
+ }
+ }
+ CareAve /= Gia_ManCoNum(p)/nOuts;
+ Gia_ManHashStop( pNew );
+ Gia_ManForEachCo( p, pObj, k )
+ pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
+ Gia_ObjComputeTruthTableStop( p );
+ Vec_IntFree( vLeaves );
+ Vec_WrdFreeP( &vSimI );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ printf( "Using patterns with count %d and higher as cares. Average care set is %8.4f %%. ", Thresh, CareAve );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+ if ( 0 )
+ {
+ FILE * pTable = fopen( "stats.txt", "a+" );
+ fprintf( pTable, "%0.2f ", CareAve );
+ fclose( pTable );
+ }
+ ABC_FREE( pTruthsTry );
+ return pNew;
+}
+
+#ifdef ABC_USE_CUDD
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDoMuxMapping( Gia_Man_t * p )
+{
+ extern Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars );
+ Gia_Man_t * pTemp, * pNew = Gia_ManDup( p );
+ Jf_Par_t Pars, * pPars = &Pars; int c, nIters = 2;
+ Sfm_Par_t Pars2, * pPars2 = &Pars2;
+ Lf_ManSetDefaultPars( pPars );
+ Sfm_ParSetDefault( pPars2 );
+ pPars2->nTfoLevMax = 5;
+ pPars2->nDepthMax = 100;
+ pPars2->nWinSizeMax = 2000;
+ for ( c = 0; c < nIters; c++ )
+ {
+ pNew = Lf_ManPerformMapping( pTemp = pNew, pPars );
+ Gia_ManStop( pTemp );
+ pNew = Gia_ManPerformMfs( pTemp = pNew, pPars2 );
+ Gia_ManStop( pTemp );
+ if ( c == nIters-1 )
+ break;
+ pNew = (Gia_Man_t *)Dsm_ManDeriveGia( pTemp = pNew, 0 );
+ Gia_ManStop( pTemp );
+ }
+ return pNew;
+}
+Gia_Man_t * Gia_ManDoMuxTransform( Gia_Man_t * p, int fReorder )
+{
+ extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
+ extern int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit, int fReorder, int fUseAdd );
+ Gia_Man_t * pRes = NULL;
+ Aig_Man_t * pMan = Gia_ManToAig( p, 0 );
+ Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan );
+ Abc_Ntk_t * pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ pNtk->pName = Extra_UtilStrsav( pMan->pName );
+ Aig_ManStop( pMan );
+ //pNtkNew = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 );
+ if ( Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, 1000000, fReorder, 0 ) )
+ {
+ Abc_Ntk_t * pStrash = Abc_NtkStrash( pNtkNew, 1, 1, 0 );
+ pRes = Abc_NtkStrashToGia( pStrash );
+ Abc_NtkDelete( pStrash );
+ }
+ Abc_NtkDelete( pNtkNew );
+ Abc_NtkDelete( pNtk );
+ return pRes;
+}
+int Gia_ManDoTest1( Gia_Man_t * p, int fReorder )
+{
+ Gia_Man_t * pTemp, * pNew; int Res;
+ pNew = Gia_ManDoMuxTransform( p, fReorder );
+ pNew = Gia_ManDoMuxMapping( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ Res = Gia_ManLutNum( pNew );
+ Gia_ManStop( pNew );
+ return Res;
+}
+Abc_Ntk_t * Gia_ManDoTest2( Gia_Man_t * p, int fReorder, int fTryNew )
+{
+ extern Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs );
+ Abc_Ntk_t * pNtkNew;
+ Gia_Man_t * pTemp, * pNew;
+ pNew = fTryNew ? Gia_ManDup(p) : Gia_ManDoMuxTransform( p, fReorder );
+ pNew = Gia_ManDoMuxMapping( pTemp = pNew );
+ Gia_ManStop( pTemp );
+ pNtkNew = Abc_NtkFromMappedGia( pNew, 0, 0 );
+ pNtkNew->pName = Extra_UtilStrsav(p->pName);
+ Gia_ManStop( pNew );
+ Abc_NtkToSop( pNtkNew, 1, ABC_INFINITY );
+ return pNtkNew;
+}
+Abc_Ntk_t * Abc_NtkMapTransform( Gia_Man_t * p, int nOuts, int fUseFixed, int fTryNew, int fVerbose )
+{
+ extern Abc_Ntk_t * Abc_NtkSpecialMapping( Abc_Ntk_t * pNtk, int fVerbose );
+ int i, k, g, nGroups = Gia_ManCoNum(p) / nOuts, CountsAll[3] = {0};
+ Abc_Obj_t * pObjNew, * pFaninNew; Gia_Obj_t * pObj;
+ Abc_Ntk_t * pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
+ assert( Gia_ManCoNum(p) % nOuts == 0 );
+ pNtkNew->pName = Extra_UtilStrsav(p->pName);
+ pNtkNew->pSpec = Extra_UtilStrsav(p->pSpec);
+ Gia_ManFillValue( p );
+ Gia_ManForEachPi( p, pObj, i )
+ Abc_NtkCreatePi( pNtkNew );
+ Gia_ManForEachPo( p, pObj, i )
+ Abc_NtkCreatePo( pNtkNew );
+ assert( nOuts <= 64 );
+ for ( g = 0; g < nGroups; g++ )
+ {
+ Gia_Man_t * pNew; Aig_Man_t * pMan;
+ Abc_Ntk_t * pNtk, * pNtkRes, * pNtkMap;
+ int pPos[64], Counter = 0, Counts[3] = {0};
+ for ( i = 0; i < nOuts; i++ )
+ pPos[i] = g*nOuts+i;
+ pNew = Gia_ManDupCones( p, pPos, nOuts, 1 );
+ if ( !fUseFixed )
+ pNtkMap = Gia_ManDoTest2( pNew, 1, fTryNew );
+ else
+ {
+ pMan = Gia_ManToAig( pNew, 0 );
+ pNtk = Abc_NtkFromAigPhase( pMan );
+ Aig_ManStop( pMan );
+ pNtkRes = Abc_NtkBddToMuxes( pNtk, 1, 1000000, 1 );
+ Abc_NtkDelete( pNtk );
+ pNtkMap = Abc_NtkSpecialMapping( pNtkRes, 0 );
+ Abc_NtkDelete( pNtkRes );
+ }
+ Gia_ManStop( pNew );
+ Gia_ManForEachCi( p, pObj, i )
+ if ( ~pObj->Value )
+ Abc_NtkCi(pNtkMap, Counter++)->pCopy = Abc_NtkCi(pNtkNew, i);
+ assert( Counter == Abc_NtkCiNum(pNtkMap) );
+ Abc_NtkForEachNode( pNtkMap, pObjNew, i )
+ {
+ pObjNew->pCopy = Abc_NtkDupObj( pNtkNew, pObjNew, 0 );
+ pObjNew->pCopy->fPersist = pObjNew->fPersist;
+ if ( pObjNew->fPersist )
+ Counts[1]++;
+ else
+ Counts[0]++;
+ Abc_ObjForEachFanin( pObjNew, pFaninNew, k )
+ Abc_ObjAddFanin( pObjNew->pCopy, pFaninNew->pCopy );
+ }
+ Abc_NtkForEachCo( pNtkMap, pObjNew, i )
+ Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, g*nOuts+i), Abc_ObjFanin0(pObjNew)->pCopy );
+ Abc_NtkDelete( pNtkMap );
+
+ if ( fVerbose )
+ {
+ printf( "%3d / %3d : ", g, nGroups );
+ printf( "Test = %4d ", Counts[0] );
+ printf( "MarkA = %4d ", Counts[1] );
+ printf( "MarkB = %4d ", Counts[2] );
+ printf( "\n" );
+ }
+
+ CountsAll[0] += Counts[0];
+ CountsAll[1] += Counts[1];
+ CountsAll[2] += Counts[2];
+ }
+ if ( fVerbose )
+ printf( "Total LUT count = %5d. MarkA = %5d. MarkB = %5d.\n", CountsAll[0], CountsAll[1], CountsAll[2] );
+ // create names
+ Abc_NtkAddDummyPiNames( pNtkNew );
+ Abc_NtkAddDummyPoNames( pNtkNew );
+ Abc_NtkAddDummyBoxNames( pNtkNew );
+ // check the resulting AIG
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ Abc_Print( 1, "Abc_NtkFromMappedGia(): Network check has failed.\n" );
+ return pNtkNew;
+}
+
+Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose )
+{
+ int fPrintOnly = 0;
+ int Res1, Res2, Result = 0;
+ int g, nGroups = Gia_ManCoNum(p) / GroupSize;
+ assert( Gia_ManCoNum(p) % GroupSize == 0 );
+ assert( GroupSize <= 64 );
+ if ( fPrintOnly )
+ {
+ for ( g = 0; g < nGroups; g++ )
+ {
+ Gia_Man_t * pNew;
+ int o, pPos[64];
+ for ( o = 0; o < GroupSize; o++ )
+ pPos[o] = g*GroupSize+o;
+ pNew = Gia_ManDupCones( p, pPos, GroupSize, 0 );
+ printf( "%3d / %3d : ", g, nGroups );
+ printf( "Test1 = %4d ", Res1 = Gia_ManDoTest1(pNew, 0) );
+ printf( "Test2 = %4d ", Res2 = Gia_ManDoTest1(pNew, 1) );
+ printf( "Test = %4d ", Abc_MinInt(Res1, Res2) );
+ printf( "\n" );
+ Result += Abc_MinInt(Res1, Res2);
+ //Gia_ManPrintStats( pNew, NULL );
+ Gia_ManStop( pNew );
+ }
+ printf( "Total LUT count = %d.\n", Result );
+ return NULL;
+
+ }
+ return Abc_NtkMapTransform( p, GroupSize, fUseFixed, fTryNew, fVerbose );
+}
+
+#else
+
+Abc_Ntk_t * Gia_ManPerformLNetMap( Gia_Man_t * p, int GroupSize, int fUseFixed, int fTryNew, int fVerbose )
+{
+ return NULL;
+}
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+