summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2013-08-12 23:27:20 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2013-08-12 23:27:20 -0700
commitfcfafb06017e50144966cd4d56dfac77123ae03c (patch)
tree19530feac7ee2d1cd912939dc5d46af3bfd1571b
parentae27704c13b8b964ec5e82d685693a2c782744d0 (diff)
downloadabc-fcfafb06017e50144966cd4d56dfac77123ae03c.tar.gz
abc-fcfafb06017e50144966cd4d56dfac77123ae03c.tar.bz2
abc-fcfafb06017e50144966cd4d56dfac77123ae03c.zip
Enabling additional matching feature in the LUT mapper.
-rw-r--r--abclib.dsp4
-rw-r--r--src/aig/gia/giaIf.c29
-rw-r--r--src/base/abci/abc.c38
-rw-r--r--src/map/if/if.h5
-rw-r--r--src/map/if/ifCut.c2
-rw-r--r--src/map/if/ifDec07.c2
-rw-r--r--src/map/if/ifDec16.c127
-rw-r--r--src/map/if/ifDec75.c341
-rw-r--r--src/map/if/module.make1
-rw-r--r--src/misc/util/utilTruth.h44
-rw-r--r--src/opt/dau/dau.h1
11 files changed, 586 insertions, 8 deletions
diff --git a/abclib.dsp b/abclib.dsp
index b0c8616b..79aaf496 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -2299,6 +2299,10 @@ SOURCE=.\src\map\if\ifDec16.c
# End Source File
# Begin Source File
+SOURCE=.\src\map\if\ifDec75.c
+# End Source File
+# Begin Source File
+
SOURCE=.\src\map\if\ifLibBox.c
# End Source File
# Begin Source File
diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c
index 278381cb..583e178a 100644
--- a/src/aig/gia/giaIf.c
+++ b/src/aig/gia/giaIf.c
@@ -235,6 +235,34 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p )
Abc_Print( 1, "lev =%5d ", LevelMax );
Abc_Print( 1, "mem =%5.2f MB", 4.0*(Gia_ManObjNum(p) + 2*nLuts + nFanins)/(1<<20) );
Abc_Print( 1, "\n" );
+
+ {
+ char * pFileName = "stats_map.txt";
+ static char FileNameOld[1000] = {0};
+ static int nNodesOld, nAreaOld, nDelayOld;
+ static abctime clk = 0;
+ FILE * pTable = fopen( pFileName, "a+" );
+ if ( strcmp( FileNameOld, p->pName ) )
+ {
+ sprintf( FileNameOld, "%s", p->pName );
+ fprintf( pTable, "\n" );
+ fprintf( pTable, "%s ", p->pName );
+ fprintf( pTable, "%d ", Gia_ManCiNum(p) );
+ fprintf( pTable, "%d ", Gia_ManCoNum(p) );
+ fprintf( pTable, "%d ", Gia_ManAndNum(p) );
+ fprintf( pTable, "%d ", nLuts );
+ fprintf( pTable, "%d ", LevelMax );
+ clk = Abc_Clock();
+ }
+ else
+ {
+ fprintf( pTable, " " );
+ fprintf( pTable, "%d ", nLuts );
+ fprintf( pTable, "%d ", LevelMax );
+// fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC );
+ }
+ fclose( pTable );
+ }
}
/**Function*************************************************************
@@ -344,6 +372,7 @@ void Gia_ManChoiceLevel_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
if ( LevelMax < Gia_ObjLevel(p, pNext) )
LevelMax = Gia_ObjLevel(p, pNext);
LevelMax++;
+ assert( LevelMax > 0 );
// get the level of the nodes in the choice node
if ( (pNext = Gia_ObjSiblObj(p, Gia_ObjId(p, pObj))) )
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index e48886be..399183ab 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -29192,7 +29192,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
}
pPars->pLutLib = (If_LibLut_t *)pAbc->pLibLut;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGDEWSqaflepmrsdbgyojikczvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "KCFAGDEWSqalepmrsdbgyojikfuczvh" ) ) != EOF )
{
switch ( c )
{
@@ -29309,9 +29309,6 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'r':
pPars->fExpRed ^= 1;
break;
- case 'f':
- pPars->fFancy ^= 1;
- break;
case 'l':
pPars->fLatchPaths ^= 1;
break;
@@ -29351,6 +29348,12 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'k':
pPars->fEnableCheck10 ^= 1;
break;
+ case 'f':
+ pPars->fEnableCheck75 ^= 1;
+ break;
+ case 'u':
+ pPars->fEnableCheck75u ^= 1;
+ break;
case 'c':
pPars->fEnableRealPos ^= 1;
break;
@@ -29416,7 +29419,7 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->fCutMin = 1;
}
- if ( pPars->fEnableCheck07 + pPars->fEnableCheck08 + pPars->fEnableCheck10 + (pPars->pLutStruct != NULL) > 1 )
+ if ( pPars->fEnableCheck07 + pPars->fEnableCheck08 + pPars->fEnableCheck10 + pPars->fEnableCheck75 + pPars->fEnableCheck75u + (pPars->pLutStruct != NULL) > 1 )
{
Abc_Print( -1, "Only one additional check can be performed at the same time.\n" );
return 1;
@@ -29451,6 +29454,26 @@ int Abc_CommandAbc9If( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->pFuncCell = If_CutPerformCheck10;
pPars->fCutMin = 1;
}
+ if ( pPars->fEnableCheck75 )
+ {
+ if ( pPars->nLutSize < 6 || pPars->nLutSize > 8 )
+ {
+ Abc_Print( -1, "This feature only works for {6,7,8}-LUTs.\n" );
+ return 1;
+ }
+ pPars->pFuncCell = If_CutPerformCheck75;
+ pPars->fCutMin = 1;
+ }
+ if ( pPars->fEnableCheck75u )
+ {
+ if ( pPars->nLutSize < 6 || pPars->nLutSize > 8 )
+ {
+ Abc_Print( -1, "This feature only works for {6,7,8}-LUTs.\n" );
+ return 1;
+ }
+ pPars->pFuncCell = If_CutPerformCheck75;
+ pPars->fCutMin = 1;
+ }
if ( pPars->pLutStruct )
{
if ( pPars->nLutSize < 6 || pPars->nLutSize > 16 )
@@ -29536,7 +29559,7 @@ usage:
sprintf(LutSize, "library" );
else
sprintf(LutSize, "%d", pPars->nLutSize );
- Abc_Print( -2, "usage: &if [-KCFAG num] [-DEW float] [-S str] [-qarlepmsdbgyojikczvh]\n" );
+ Abc_Print( -2, "usage: &if [-KCFAG num] [-DEW float] [-S str] [-qarlepmsdbgyojikfuczvh]\n" );
Abc_Print( -2, "\t performs FPGA technology mapping of the network\n" );
Abc_Print( -2, "\t-K num : the number of LUT inputs (2 < num < %d) [default = %s]\n", IF_MAX_LUTSIZE+1, LutSize );
Abc_Print( -2, "\t-C num : the max number of priority cuts (0 < num < 2^12) [default = %d]\n", pPars->nCutsMax );
@@ -29549,7 +29572,6 @@ usage:
Abc_Print( -2, "\t-S str : string representing the LUT structure [default = %s]\n", pPars->pLutStruct ? pPars->pLutStruct : "not used" );
Abc_Print( -2, "\t-q : toggles preprocessing using several starting points [default = %s]\n", pPars->fPreprocess? "yes": "no" );
Abc_Print( -2, "\t-a : toggles area-oriented mapping [default = %s]\n", pPars->fArea? "yes": "no" );
-// Abc_Print( -2, "\t-f : toggles one fancy feature [default = %s]\n", pPars->fFancy? "yes": "no" );
Abc_Print( -2, "\t-r : enables expansion/reduction of the best cuts [default = %s]\n", pPars->fExpRed? "yes": "no" );
Abc_Print( -2, "\t-l : optimizes latch paths for delay, other paths for area [default = %s]\n", pPars->fLatchPaths? "yes": "no" );
Abc_Print( -2, "\t-e : uses edge-based cut selection heuristics [default = %s]\n", pPars->fEdge? "yes": "no" );
@@ -29564,6 +29586,8 @@ usage:
Abc_Print( -2, "\t-j : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck07? "yes": "no" );
Abc_Print( -2, "\t-i : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck08? "yes": "no" );
Abc_Print( -2, "\t-k : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck10? "yes": "no" );
+ Abc_Print( -2, "\t-f : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75? "yes": "no" );
+ Abc_Print( -2, "\t-u : toggles enabling additional check [default = %s]\n", pPars->fEnableCheck75u? "yes": "no" );
Abc_Print( -2, "\t-c : toggles enabling additional feature [default = %s]\n", pPars->fEnableRealPos? "yes": "no" );
Abc_Print( -2, "\t-z : toggles deriving LUTs when mapping into LUT structures [default = %s]\n", pPars->fDeriveLuts? "yes": "no" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
diff --git a/src/map/if/if.h b/src/map/if/if.h
index be787a0b..5076bb28 100644
--- a/src/map/if/if.h
+++ b/src/map/if/if.h
@@ -117,6 +117,8 @@ struct If_Par_t_
int fEnableCheck07;// enable additional checking
int fEnableCheck08;// enable additional checking
int fEnableCheck10;// enable additional checking
+ int fEnableCheck75;// enable additional checking
+ int fEnableCheck75u;// enable additional checking
int fEnableRealPos;// enable additional feature
int fUseDsd; // compute DSD of the cut functions
int fDeriveLuts; // enables deriving LUT structures
@@ -492,6 +494,9 @@ extern int If_CutPerformCheck07( If_Man_t * p, unsigned * pTruth, in
extern int If_CutPerformCheck08( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck10( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern int If_CutPerformCheck16( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
+extern int If_CutPerformCheck45( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
+extern int If_CutPerformCheck54( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
+extern int If_CutPerformCheck75( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
extern float If_CutDelayLutStruct( If_Man_t * p, If_Cut_t * pCut, char * pStr, float WireDelay );
extern int If_CluCheckExt( void * p, word * pTruth, int nVars, int nLutLeaf, int nLutRoot,
char * pLut0, char * pLut1, word * pFunc0, word * pFunc1 );
diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c
index 78f9ec68..c9edc66b 100644
--- a/src/map/if/ifCut.c
+++ b/src/map/if/ifCut.c
@@ -856,7 +856,7 @@ void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut )
return;
}
- if ( (p->pPars->fUseDsd || p->pPars->fUseBat || p->pPars->fEnableCheck07 || p->pPars->fEnableCheck08 || p->pPars->fEnableCheck10 || p->pPars->pLutStruct || p->pPars->fUserRecLib) && !pCut->fUseless )
+ if ( (p->pPars->fUseDsd || p->pPars->fUseBat || p->pPars->fEnableCheck07 || p->pPars->fEnableCheck08 || p->pPars->fEnableCheck10 || p->pPars->fEnableCheck75 || p->pPars->fEnableCheck75u || p->pPars->pLutStruct || p->pPars->fUserRecLib) && !pCut->fUseless )
{
If_Cut_t * pFirst = pCutSet->ppCuts[0];
if ( pFirst->fUseless || If_ManSortCompare(p, pFirst, pCut) == 1 )
diff --git a/src/map/if/ifDec07.c b/src/map/if/ifDec07.c
index 6d454a96..4c586ed8 100644
--- a/src/map/if/ifDec07.c
+++ b/src/map/if/ifDec07.c
@@ -455,10 +455,12 @@ word If_Dec7Perform( word t0[2], int fDerive )
// start arrays
for ( i = 0; i < 7; i++ )
{
+/*
if ( i < 6 )
assert( If_Dec6HasVar( t[0], i ) || If_Dec6HasVar( t[1], i ) );
else
assert( t[0] != t[1] );
+*/
Pla2Var[i] = Var2Pla[i] = i;
}
// generate permutations
diff --git a/src/map/if/ifDec16.c b/src/map/if/ifDec16.c
index e349f6eb..729b0489 100644
--- a/src/map/if/ifDec16.c
+++ b/src/map/if/ifDec16.c
@@ -1749,6 +1749,133 @@ If_Grp_t If_CluCheck( If_Man_t * p, word * pTruth0, int nVars, int iVarStart, in
return G1;
}
+
+static inline word Abc_Tt6Cofactor0( word t, int iVar )
+{
+ assert( iVar >= 0 && iVar < 6 );
+ return (t &~Truth6[iVar]) | ((t &~Truth6[iVar]) << (1<<iVar));
+}
+static inline word Abc_Tt6Cofactor1( word t, int iVar )
+{
+ assert( iVar >= 0 && iVar < 6 );
+ return (t & Truth6[iVar]) | ((t & Truth6[iVar]) >> (1<<iVar));
+}
+int If_CluCheckDecIn( word t, int nVars )
+{
+ int v, u, Cof2[2], Cof4[4];
+// for ( v = 0; v < nVars; v++ )
+ for ( v = 0; v < 1; v++ ) // restrict to the first (decomposed) input
+ {
+ Cof2[0] = Abc_Tt6Cofactor0( t, v );
+ Cof2[1] = Abc_Tt6Cofactor1( t, v );
+ for ( u = v+1; u < nVars; u++ )
+ {
+ Cof4[0] = Abc_Tt6Cofactor0( Cof2[0], u );
+ Cof4[1] = Abc_Tt6Cofactor1( Cof2[0], u );
+ Cof4[2] = Abc_Tt6Cofactor0( Cof2[1], u );
+ Cof4[3] = Abc_Tt6Cofactor1( Cof2[1], u );
+ if ( Cof4[0] == Cof4[1] && Cof4[0] == Cof4[2] )
+ return 1;
+ if ( Cof4[0] == Cof4[2] && Cof4[0] == Cof4[3] )
+ return 1;
+ if ( Cof4[0] == Cof4[1] && Cof4[0] == Cof4[3] )
+ return 1;
+ if ( Cof4[1] == Cof4[2] && Cof4[1] == Cof4[3] )
+ return 1;
+ }
+ }
+ return 0;
+}
+int If_CluCheckDecInU( word t, int nVars )
+{
+ int v, u, Cof2[2], Cof4[4];
+// for ( v = 0; v < nVars; v++ )
+ for ( v = 0; v < 1; v++ ) // restrict to the first (decomposed) input
+ {
+ Cof2[0] = Abc_Tt6Cofactor0( t, v );
+ Cof2[1] = Abc_Tt6Cofactor1( t, v );
+ for ( u = v+1; u < nVars; u++ )
+ {
+ Cof4[0] = Abc_Tt6Cofactor0( Cof2[0], u );
+ Cof4[1] = Abc_Tt6Cofactor1( Cof2[0], u );
+ Cof4[2] = Abc_Tt6Cofactor0( Cof2[1], u );
+ Cof4[3] = Abc_Tt6Cofactor1( Cof2[1], u );
+ if ( Cof4[0] == Cof4[1] && Cof4[0] == Cof4[2] )
+ return 1;
+ if ( Cof4[0] == Cof4[2] && Cof4[0] == Cof4[3] )
+ return 1;
+ }
+ }
+ return 0;
+}
+int If_CluCheckDecOut( word t, int nVars )
+{
+ int v;
+ for ( v = 0; v < nVars; v++ )
+ if (
+ (t & Truth6[v]) == 0 || // F * !a
+ (~t & Truth6[v]) == 0 || // !F * !a
+ (t & ~Truth6[v]) == 0 || // F * a
+ (~t & ~Truth6[v]) == 0 // !F * a
+ )
+ return 1;
+ return 0;
+}
+int If_CluCheckDecOutU( word t, int nVars )
+{
+ int v;
+ for ( v = 0; v < nVars; v++ )
+ if (
+ (t & ~Truth6[v]) == 0 || // F * a
+ (~t & ~Truth6[v]) == 0 // !F * a
+ )
+ return 1;
+ return 0;
+}
+
+int If_CutPerformCheck45( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr )
+{
+ // 5LUT -> 4LUT
+ If_Grp_t G, R;
+ word Func0, Func1;
+ G = If_CluCheck( p, (word *)pTruth, nLeaves, 0, 5, 4, &R, &Func0, &Func1, NULL, 0 );
+ if ( G.nVars == 0 )
+ return 0;
+ Func0 = If_CluAdjust( Func0, R.nVars );
+ Func1 = If_CluAdjust( Func1, G.nVars );
+#if 0
+ Kit_DsdPrintFromTruth( pTruth, nVars ); printf( "\n" );
+ Kit_DsdPrintFromTruth( (unsigned*)&Func0, R.nVars ); printf( "\n" );
+ Kit_DsdPrintFromTruth( (unsigned*)&Func1, G.nVars ); printf( "\n" );
+ If_CluPrintGroup( &R );
+ If_CluPrintGroup( &G );
+#endif
+ if ( G.nVars < 5 || (p->pPars->fEnableCheck75 && If_CluCheckDecOut(Func1, 5)) || (p->pPars->fEnableCheck75u && If_CluCheckDecOutU(Func1, 5)) )
+ return 1;
+ return 0;
+}
+int If_CutPerformCheck54( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr )
+{
+ // 4LUT -> 5LUT
+ If_Grp_t G, R;
+ word Func0, Func1;
+ G = If_CluCheck( p, (word *)pTruth, nLeaves, 0, 4, 5, &R, &Func0, &Func1, NULL, 0 );
+ if ( G.nVars == 0 )
+ return 0;
+ Func0 = If_CluAdjust( Func0, R.nVars );
+ Func1 = If_CluAdjust( Func1, G.nVars );
+#if 0
+ Kit_DsdPrintFromTruth( pTruth, nVars ); printf( "\n" );
+ Kit_DsdPrintFromTruth( (unsigned*)&Func0, R.nVars ); printf( "\n" );
+ Kit_DsdPrintFromTruth( (unsigned*)&Func1, G.nVars ); printf( "\n" );
+ If_CluPrintGroup( &R );
+ If_CluPrintGroup( &G );
+#endif
+ if ( R.nVars < 5 || (p->pPars->fEnableCheck75 && If_CluCheckDecIn(Func0, 5)) || (p->pPars->fEnableCheck75u && If_CluCheckDecInU(Func0, 5)) )
+ return 1;
+ return 0;
+}
+
// returns the best group found
If_Grp_t If_CluCheck3( If_Man_t * p, word * pTruth0, int nVars, int nLutLeaf, int nLutLeaf2, int nLutRoot,
If_Grp_t * pR, If_Grp_t * pG2, word * pFunc0, word * pFunc1, word * pFunc2 )
diff --git a/src/map/if/ifDec75.c b/src/map/if/ifDec75.c
new file mode 100644
index 00000000..0135f87d
--- /dev/null
+++ b/src/map/if/ifDec75.c
@@ -0,0 +1,341 @@
+/**CFile****************************************************************
+
+ FileName [ifDec75.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [FPGA mapping based on priority cuts.]
+
+ Synopsis [Performs additional check.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - November 21, 2006.]
+
+ Revision [$Id: ifDec75.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "if.h"
+#include "misc/extra/extra.h"
+#include "bool/kit/kit.h"
+#include "opt/dau/dau.h"
+#include "misc/util/utilTruth.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Finds all boundsets for which decomposition exists.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Dau_DsdCheckDecExist_rec( char * pStr, char ** p, int * pMatches, int * pnSupp )
+{
+ if ( **p == '!' )
+ (*p)++;
+ while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
+ (*p)++;
+ if ( **p >= 'a' && **p <= 'z' ) // var
+ {
+ (*pnSupp)++;
+ return 0;
+ }
+ if ( **p == '(' || **p == '[' ) // and/xor
+ {
+ unsigned Mask = 0;
+ int m, pSupps[8] = {0}, nParts = 0, nMints;
+ char * q = pStr + pMatches[ *p - pStr ];
+ assert( *q == **p + 1 + (**p != '(') );
+ for ( (*p)++; *p < q; (*p)++ )
+ {
+ Mask |= Dau_DsdCheckDecExist_rec( pStr, p, pMatches, &pSupps[nParts] );
+ *pnSupp += pSupps[nParts++];
+ }
+ assert( *p == q );
+ assert( nParts > 1 );
+ nMints = (1 << nParts);
+ for ( m = 1; m < nMints; m++ )
+ {
+ int i, Sum = 0;
+ for ( i = 0; i < nParts; i++ )
+ if ( (m >> i) & 1 )
+ Sum += pSupps[i];
+ assert( Sum > 0 && Sum <= 8 );
+ if ( Sum >= 2 )
+ Mask |= (1 << Sum);
+ }
+ return Mask;
+ }
+ if ( **p == '<' || **p == '{' ) // mux
+ {
+ int uSupp;
+ unsigned Mask = 0;
+ char * q = pStr + pMatches[ *p - pStr ];
+ assert( *q == **p + 1 + (**p != '(') );
+ for ( (*p)++; *p < q; (*p)++ )
+ {
+ uSupp = 0;
+ Mask |= Dau_DsdCheckDecExist_rec( pStr, p, pMatches, &uSupp );
+ *pnSupp += uSupp;
+ }
+ assert( *p == q );
+ Mask |= (1 << *pnSupp);
+ return Mask;
+ }
+ assert( 0 );
+ return 0;
+}
+int Dau_DsdCheckDecExist( char * pDsd )
+{
+ int nSupp = 0;
+ if ( pDsd[1] == 0 )
+ return 0;
+ return Dau_DsdCheckDecExist_rec( pDsd, &pDsd, Dau_DsdComputeMatches(pDsd), &nSupp );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finds all boundsets for which AND-decomposition exists.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Dau_DsdCheckDecAndExist_rec( char * pStr, char ** p, int * pMatches, int * pnSupp )
+{
+ if ( **p == '!' )
+ (*p)++;
+ while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') )
+ (*p)++;
+ if ( **p >= 'a' && **p <= 'z' ) // var
+ {
+ (*pnSupp)++;
+ return 0;
+ }
+ if ( **p == '(' ) // and
+ {
+ unsigned Mask = 0;
+ int m, i, pSupps[8] = {0}, nParts = 0, nSimple = 0, nMints;
+ char * q = pStr + pMatches[ *p - pStr ];
+ assert( *q == **p + 1 + (**p != '(') );
+ for ( (*p)++; *p < q; (*p)++ )
+ {
+ Mask |= Dau_DsdCheckDecAndExist_rec( pStr, p, pMatches, &pSupps[nParts] );
+ nSimple += (pSupps[nParts] == 1);
+ *pnSupp += pSupps[nParts++];
+ }
+ assert( *p == q );
+ assert( nParts > 1 );
+ if ( nSimple > 0 )
+ {
+ nMints = (1 << nParts);
+ for ( m = 1; m < nMints; m++ )
+ {
+ int Sum = 0;
+ for ( i = 0; i < nParts; i++ )
+ if ( pSupps[i] > 1 && ((m >> i) & 1) )
+ Sum += pSupps[i];
+ assert( Sum <= 8 );
+ if ( Sum >= 2 )
+ for ( i = 0; i < nSimple; i++ )
+ Mask |= (1 << (Sum + i));
+ }
+ for ( i = 2; i < nSimple; i++ )
+ Mask |= (1 << i);
+ }
+ return Mask;
+ }
+ if ( **p == '<' || **p == '{' || **p == '[' ) // mux/xor/nondec
+ {
+ int uSupp;
+ unsigned Mask = 0;
+ char * q = pStr + pMatches[ *p - pStr ];
+ assert( *q == **p + 1 + (**p != '(') );
+ for ( (*p)++; *p < q; (*p)++ )
+ {
+ uSupp = 0;
+ Mask |= Dau_DsdCheckDecAndExist_rec( pStr, p, pMatches, &uSupp );
+ *pnSupp += uSupp;
+ }
+ assert( *p == q );
+ return Mask;
+ }
+ assert( 0 );
+ return 0;
+}
+int Dau_DsdCheckDecAndExist( char * pDsd )
+{
+ int nSupp = 0;
+ if ( pDsd[1] == 0 )
+ return 1;
+ return Dau_DsdCheckDecAndExist_rec( pDsd, &pDsd, Dau_DsdComputeMatches(pDsd), &nSupp );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs additional check.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int If_CutPerformCheck75__( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr )
+{
+ char pDsdStr[1000];
+ int fDerive = 0;
+ int nSizeNonDec, nDecExists, nDecAndExists;
+ static int Counter = 0;
+ Counter++;
+ if ( nLeaves < 6 )
+ return 1;
+ assert( nLeaves <= 8 );
+ if ( nLeaves < 8 && If_CutPerformCheck16( p, pTruth, nVars, nLeaves, "44" ) )
+ return 1;
+ // check decomposability
+ nSizeNonDec = Dau_DsdDecompose( (word *)pTruth, nLeaves, 0, 0, pDsdStr );
+// printf( "Vars = %d %s", nLeaves, pDsdStr ); printf( "\n" );
+// Extra_PrintBinary( stdout, &nDecExists, 8 ); printf( "\n" );
+// Extra_PrintBinary( stdout, &nDecAndExists, 8 ); printf( "\n" );
+ if ( nLeaves == 8 )
+ {
+ if ( nSizeNonDec >= 5 )
+ return 0;
+ nDecAndExists = Dau_DsdCheckDecAndExist( pDsdStr );
+ if ( nDecAndExists & 0x10 ) // bit 4
+ return 1;
+ else
+ return 0;
+ }
+ if ( nLeaves == 7 )
+ {
+ extern void If_Dec7MinimumBase( word uTruth[2], int * pSupp, int nVarsAll, int * pnVars );
+ word * pT = (word *)pTruth;
+ word pCof0[2], pCof1[2];
+ int v, nVarsMin;
+ if ( nSizeNonDec < 5 )
+ {
+ nDecExists = Dau_DsdCheckDecExist( pDsdStr );
+ if ( nDecExists & 0x10 ) // bit 4
+ return 1;
+ nDecAndExists = Dau_DsdCheckDecAndExist( pDsdStr );
+ if ( nDecAndExists & 0x18 ) // bit 4, 3
+ return 1;
+ }
+ // check cofactors
+ for ( v = 0; v < 7; v++ )
+ {
+ pCof0[0] = pCof1[0] = pT[0];
+ pCof0[1] = pCof1[1] = pT[1];
+ Abc_TtCofactor0( pCof0, 2, v );
+ Abc_TtCofactor1( pCof1, 2, v );
+ if ( Abc_TtSupportSize(pCof0, 7) < 4 )
+ {
+ If_Dec7MinimumBase( pCof1, NULL, 7, &nVarsMin );
+ nSizeNonDec = Dau_DsdDecompose( pCof1, nVarsMin, 0, 0, pDsdStr );
+ if ( nSizeNonDec >= 5 )
+ continue;
+ nDecExists = Dau_DsdCheckDecExist( pDsdStr );
+ if ( nDecExists & 0x18 ) // bit 4, 3
+ return 1;
+ }
+ else if ( Abc_TtSupportSize(pCof1, 7) < 4 )
+ {
+ If_Dec7MinimumBase( pCof0, NULL, 7, &nVarsMin );
+ nSizeNonDec = Dau_DsdDecompose( pCof0, nVarsMin, 0, 0, pDsdStr );
+ if ( nSizeNonDec >= 5 )
+ continue;
+ nDecExists = Dau_DsdCheckDecExist( pDsdStr );
+ if ( nDecExists & 0x18 ) // bit 4, 3
+ return 1;
+ }
+ }
+ return 0;
+ }
+ if ( nLeaves == 6 )
+ {
+ if ( nSizeNonDec < 5 )
+ {
+ nDecExists = Dau_DsdCheckDecExist( pDsdStr );
+ if ( nDecExists & 0x18 ) // bit 4, 3
+ return 1;
+ nDecAndExists = Dau_DsdCheckDecAndExist( pDsdStr );
+ if ( nDecAndExists & 0x1C ) // bit 4, 3, 2
+ return 1;
+ }
+ return If_CutPerformCheck07( p, pTruth, nVars, nLeaves, pStr );
+ }
+ assert( 0 );
+ return 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs additional check.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int If_CutPerformCheck75( If_Man_t * p, unsigned * pTruth0, int nVars, int nLeaves, char * pStr )
+{
+ word * pTruthW = (word *)pTruth0;
+ word pTruth[4] = { pTruthW[0], pTruthW[1], pTruthW[2], pTruthW[3] };
+ assert( nLeaves <= 8 );
+ Abc_TtMinimumBase( pTruth, NULL, nLeaves, &nLeaves );
+ if ( nLeaves < 6 )
+ return 1;
+// if ( nLeaves < 8 && If_CutPerformCheck07( p, (unsigned *)pTruth, nVars, nLeaves, "44" ) )
+ if ( nLeaves < 8 && If_CutPerformCheck16( p, (unsigned *)pTruth, nVars, nLeaves, "44" ) )
+ return 1;
+ if ( p->pPars->fEnableCheck75 && nLeaves == 8 )
+ {
+// char pDsdStr[1000] = "(!(abd)!(c!([fe][gh])))";
+ char pDsdStr[1000];
+ int nSizeNonDec = Dau_DsdDecompose( (word *)pTruth, nLeaves, 0, 0, pDsdStr );
+ if ( nSizeNonDec >= 5 )
+ return 0;
+ if ( Dau_DsdCheckDecAndExist(pDsdStr) & 0x10 ) // bit 4
+ return 1;
+ return 0;
+ }
+ if ( If_CutPerformCheck45( p, (unsigned *)pTruth, nVars, nLeaves, pStr ) )
+ return 1;
+ if ( If_CutPerformCheck54( p, (unsigned *)pTruth, nVars, nLeaves, pStr ) )
+ return 1;
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/map/if/module.make b/src/map/if/module.make
index b7b08722..e80aa1c4 100644
--- a/src/map/if/module.make
+++ b/src/map/if/module.make
@@ -5,6 +5,7 @@ SRC += src/map/if/ifCom.c \
src/map/if/ifDec08.c \
src/map/if/ifDec10.c \
src/map/if/ifDec16.c \
+ src/map/if/ifDec75.c \
src/map/if/ifLibBox.c \
src/map/if/ifLibLut.c \
src/map/if/ifMan.c \
diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h
index 65b646fa..245a78fc 100644
--- a/src/misc/util/utilTruth.h
+++ b/src/misc/util/utilTruth.h
@@ -1067,6 +1067,50 @@ static inline void Abc_TtSwapVars( word * pTruth, int nVars, int iVar, int jVar
/**Function*************************************************************
+ Synopsis [Support minimization.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Abc_TtShrink( word * pF, int nVars, int nVarsAll, unsigned Phase )
+{
+ int i, k, Var = 0;
+ assert( nVarsAll <= 16 );
+ for ( i = 0; i < nVarsAll; i++ )
+ if ( Phase & (1 << i) )
+ {
+ for ( k = i-1; k >= Var; k-- )
+ Abc_TtSwapAdjacent( pF, Abc_TtWordNum(nVarsAll), k );
+ Var++;
+ }
+ assert( Var == nVars );
+}
+static inline int Abc_TtMinimumBase( word * t, int * pSupp, int nVarsAll, int * pnVars )
+{
+ int v, iVar = 0, uSupp = 0;
+ assert( nVarsAll <= 16 );
+ for ( v = 0; v < nVarsAll; v++ )
+ if ( Abc_TtHasVar( t, nVarsAll, v ) )
+ {
+ uSupp |= (1 << v);
+ if ( pSupp )
+ pSupp[iVar] = pSupp[v];
+ iVar++;
+ }
+ if ( pnVars )
+ *pnVars = iVar;
+ if ( uSupp == 0 || Abc_TtSuppIsMinBase( uSupp ) )
+ return 0;
+ Abc_TtShrink( t, iVar, nVarsAll, uSupp );
+ return 1;
+}
+
+/**Function*************************************************************
+
Synopsis [Implemeting given NPN config.]
Description []
diff --git a/src/opt/dau/dau.h b/src/opt/dau/dau.h
index 070b894d..0f332b26 100644
--- a/src/opt/dau/dau.h
+++ b/src/opt/dau/dau.h
@@ -77,6 +77,7 @@ static inline int Dau_DsdReadVar( char * p ) { if ( *p == '!' ) p++; return *p
/*=== dauCanon.c ==========================================================*/
extern unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm );
/*=== dauDsd.c ==========================================================*/
+extern int * Dau_DsdComputeMatches( char * p );
extern int Dau_DsdDecompose( word * pTruth, int nVarsInit, int fSplitPrime, int fWriteTruth, char * pRes );
extern void Dau_DsdPrintFromTruth( FILE * pFile, word * pTruth, int nVarsInit );
extern word * Dau_DsdToTruth( char * p, int nVars );