diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2017-10-01 18:00:09 +0300 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2017-10-01 18:00:09 +0300 |
commit | d3152aefa7af3a1173647b678959f70d935ae707 (patch) | |
tree | a06b823d6cd5f6a3696dea427f5f179a5a700a62 /src | |
parent | c696ae95d0130204bedfb9cb7209748fa6ab0f2e (diff) | |
download | abc-d3152aefa7af3a1173647b678959f70d935ae707.tar.gz abc-d3152aefa7af3a1173647b678959f70d935ae707.tar.bz2 abc-d3152aefa7af3a1173647b678959f70d935ae707.zip |
Exact synthesis of majority gates.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abci/abc.c | 75 | ||||
-rw-r--r-- | src/misc/util/utilTruth.h | 215 | ||||
-rw-r--r-- | src/sat/bmc/bmcMaj.c | 373 | ||||
-rw-r--r-- | src/sat/bmc/module.make | 1 |
4 files changed, 663 insertions, 1 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index d7cf43ba..5caf8145 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -149,6 +149,7 @@ static int Abc_CommandExact ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandBmsStart ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBmsStop ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBmsPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandMajExact ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandLogic ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandComb ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -815,6 +816,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_start", Abc_CommandBmsStart, 0 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_stop", Abc_CommandBmsStop, 0 ); Cmd_CommandAdd( pAbc, "Exact synthesis", "bms_ps", Abc_CommandBmsPs, 0 ); + Cmd_CommandAdd( pAbc, "Exact synthesis", "majexact", Abc_CommandMajExact, 0 ); Cmd_CommandAdd( pAbc, "Various", "logic", Abc_CommandLogic, 1 ); Cmd_CommandAdd( pAbc, "Various", "comb", Abc_CommandComb, 1 ); @@ -8068,6 +8070,79 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandMajExact( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Maj_ManExactSynthesis( int nVars, int nNodes, int fUseConst, int fVerbose ); + int c, nVars = 3, nNodes = 1, fUseConst = 0, fVerbose = 1; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "NMcvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nVars = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nVars < 0 ) + goto usage; + break; + case 'M': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-M\" should be followed by an integer.\n" ); + goto usage; + } + nNodes = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nNodes < 0 ) + goto usage; + break; + case 'c': + fUseConst ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( (nVars & 1) == 0 ) + { + Abc_Print( -1, "Cannot sythesize MAJ gate with an even number of inputs (%d).\n", nVars ); + return 1; + } + Maj_ManExactSynthesis( nVars, nNodes, fUseConst, fVerbose ); + return 0; + +usage: + Abc_Print( -2, "usage: majexact [-NM <num>] [-cvh]\n" ); + Abc_Print( -2, "\t exactly synthesizes N-input MAJ using MAJ3 gates\n" ); + Abc_Print( -2, "\t-N <num> : the number of input variables [default = %d]\n", nVars ); + Abc_Print( -2, "\t-M <num> : the number of MAJ3 nodes [default = %d]\n", nNodes ); + Abc_Print( -2, "\t-c : toggle using constant fanins [default = %s]\n", fUseConst ? "yes" : "no" ); + Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose ? "yes" : "no" ); + Abc_Print( -2, "\t-h : print the command usage\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandLogic( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk, * pNtkRes; diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index 1c03d4c7..3a9eb7c1 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -332,6 +332,12 @@ static inline void Abc_TtMux( word * pOut, word * pCtrl, word * pIn1, word * pIn for ( w = 0; w < nWords; w++ ) pOut[w] = (pCtrl[w] & pIn1[w]) | (~pCtrl[w] & pIn0[w]); } +static inline void Abc_TtMaj( word * pOut, word * pIn0, word * pIn1, word * pIn2, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + pOut[w] = (pIn0[w] & pIn1[w]) | (pIn0[w] & pIn2[w]) | (pIn1[w] & pIn2[w]); +} static inline int Abc_TtIntersect( word * pIn1, word * pIn2, int nWords, int fCompl ) { int w; @@ -417,7 +423,24 @@ static inline void Abc_TtConst1( word * pIn1, int nWords ) for ( w = 0; w < nWords; w++ ) pIn1[w] = ~(word)0; } - +static inline void Abc_TtIthVar( word * pOut, int iVar, int nVars ) +{ + int k, nWords = Abc_TtWordNum( nVars ); + if ( iVar < 6 ) + { + for ( k = 0; k < nWords; k++ ) + pOut[k] = s_Truths6[iVar]; + } + else + { + for ( k = 0; k < nWords; k++ ) + if ( k & (1 << (iVar-6)) ) + pOut[k] = ~(word)0; + else + pOut[k] = 0; + } +} + /**Function************************************************************* Synopsis [Compares Cof0 and Cof1.] @@ -2339,6 +2362,145 @@ static inline int Abc_TtCheckOutAnd( word t, int i, word * pOut ) } return -1; } +static inline int Abc_TtCheckOutAnd7( word * t, int i, word * pOut ) +{ + assert( i < 7 ); + if ( i == 6 ) + { + word c0 = t[0]; + word c1 = t[1]; + assert( c0 != c1 ); + if ( c0 == 0 ) // F = i * G + { + if ( pOut ) pOut[0] = pOut[1] = c1; + return 0; + } + if ( c1 == 0 ) // F = ~i * G + { + if ( pOut ) pOut[0] = pOut[1] = c0; + return 1; + } + if ( ~c0 == 0 ) // F = ~i + G + { + if ( pOut ) pOut[0] = pOut[1] = c1; + return 2; + } + if ( ~c1 == 0 ) // F = i + G + { + if ( pOut ) pOut[0] = pOut[1] = c0; + return 3; + } + if ( c0 == ~c1 ) // F = i # G + { + if ( pOut ) pOut[0] = pOut[1] = c0; + return 4; + } + } + else + { + int k, Res[2]; + for ( k = 0; k < 2; k++ ) + if ( (Res[k] = Abc_TtCheckOutAnd(t[k], i, pOut+k)) == -1 || Res[0] != Res[k] ) + return -1; + return Res[0]; + } + return -1; +} +static inline int Abc_TtCheckOutAnd8( word * t, int i, word * pOut ) +{ + assert( i < 8 ); + if ( i == 7 ) + { + word * c0 = t; + word * c1 = t + 2; + assert( c0[0] != c1[0] || c0[1] != c1[1] ); + if ( c0[0] == 0 && c0[1] == 0 ) // F = i * G + { + if ( pOut ) pOut[0] = pOut[2] = c1[0], pOut[1] = pOut[3] = c1[1]; + return 0; + } + if ( c1[0] == 0 && c1[1] == 0 ) // F = ~i * G + { + if ( pOut ) pOut[0] = pOut[2] = c0[0], pOut[1] = pOut[3] = c0[1]; + return 1; + } + if ( ~c0[0] == 0 && ~c0[1] == 0 ) // F = ~i + G + { + if ( pOut ) pOut[0] = pOut[2] = c1[0], pOut[1] = pOut[3] = c1[1]; + return 2; + } + if ( ~c1[0] == 0 && ~c1[1] == 0 ) // F = i + G + { + if ( pOut ) pOut[0] = pOut[2] = c0[0], pOut[1] = pOut[3] = c0[1]; + return 3; + } + if ( c0[0] == ~c1[0] && c0[1] == ~c1[1] ) // F = i # G + { + if ( pOut ) pOut[0] = pOut[2] = c0[0], pOut[1] = pOut[3] = c0[1]; + return 4; + } + } + else if ( i == 6 ) + { + int k, Res[2]; + for ( k = 0; k < 2; k++ ) + if ( (Res[k] = Abc_TtCheckOutAnd7(t+2*k, i, pOut+2*k)) == -1 || Res[0] != Res[k] ) + return -1; + return Res[0]; + } + else + { + int k, Res[4]; + for ( k = 0; k < 4; k++ ) + if ( (Res[k] = Abc_TtCheckOutAnd(t[k], i, pOut+k)) == -1 || Res[0] != Res[k] ) + return -1; + return Res[0]; + } + return -1; +} +static inline word Abc_TtCheckDecOutOne7( word * t, int * piVar, int * pType ) +{ + int v, Type, Type2; word Out; + for ( v = 6; v >= 0; v-- ) + if ( (Type = Abc_TtCheckOutAnd7(t, v, NULL)) != -1 ) + { + Abc_TtSwapVars( t, 7, v, 6 ); + Type2 = Abc_TtCheckOutAnd7(t, 6, &Out); + assert( Type == Type2 ); + *piVar = v; + *pType = Type; + return Out; + } + return 0; +} +static inline word Abc_TtCheckDecOutOne8( word * t, int * piVar1, int * piVar2, int * pType1, int * pType2 ) +{ + int v, Type1, Type12, Type2, Type22; word Out[2], Out2; + for ( v = 7; v >= 0; v-- ) + if ( (Type1 = Abc_TtCheckOutAnd8(t, v, NULL)) != -1 ) + { + Abc_TtSwapVars( t, 8, v, 7 ); + Type12 = Abc_TtCheckOutAnd8(t, 7, Out); + assert( Type1 == Type12 ); + *piVar1 = v; + *piVar2 = Type1; + break; + } + if ( v == -1 ) + return 0; + for ( v = 6; v >= 0; v-- ) + if ( (Type2 = Abc_TtCheckOutAnd7(Out, v, NULL)) != -1 && Abc_Lit2Var(Type2) == Abc_Lit2Var(Type1) ) + { + Abc_TtSwapVars( Out, 7, v, 6 ); + Type22 = Abc_TtCheckOutAnd7(t, 6, &Out2); + assert( Type2 == Type22 ); + *piVar2 = v; + *pType2 = Type2; + assert( *piVar2 < *piVar1 ); + return Out2; + } + return 0; +} /**Function************************************************************* @@ -2536,6 +2698,57 @@ static inline void Unm_ManCheckTest() } +/**Function************************************************************* + + Synopsis [Truth table evaluation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word Abc_TtEvalLut6( word Ins[6], word Lut, int nVars ) +{ + word Cube, Res = 0; int k, i; + for ( k = 0; k < (1<<nVars); k++ ) + { + if ( ((Lut >> k) & 1) == 0 ) + continue; + Cube = ~(word)0; + for ( i = 0; i < nVars; i++ ) + Cube &= ((k >> i) & 1) ? Ins[i] : ~Ins[i]; + } + return Res; +} +static inline unsigned Abc_TtEvalLut5( unsigned Ins[5], int Lut, int nVars ) +{ + unsigned Cube, Res = 0; int k, i; + for ( k = 0; k < (1<<nVars); k++ ) + { + if ( ((Lut >> k) & 1) == 0 ) + continue; + Cube = ~(unsigned)0; + for ( i = 0; i < nVars; i++ ) + Cube &= ((k >> i) & 1) ? Ins[i] : ~Ins[i]; + } + return Res; +} +static inline int Abc_TtEvalLut4( int Ins[4], int Lut, int nVars ) +{ + int Cube, Res = 0; int k, i; + for ( k = 0; k < (1<<nVars); k++ ) + { + if ( ((Lut >> k) & 1) == 0 ) + continue; + Cube = ~(int)0; + for ( i = 0; i < nVars; i++ ) + Cube &= ((k >> i) & 1) ? Ins[i] : ~Ins[i]; + } + return Res & ~(~0 << (1<<nVars)); +} + /**Function************************************************************* diff --git a/src/sat/bmc/bmcMaj.c b/src/sat/bmc/bmcMaj.c new file mode 100644 index 00000000..d22a38c9 --- /dev/null +++ b/src/sat/bmc/bmcMaj.c @@ -0,0 +1,373 @@ +/**CFile**************************************************************** + + FileName [bmcMaj.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based bounded model checking.] + + Synopsis [Exact synthesis with majority gates.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - October 1, 2017.] + + Revision [$Id: bmcMaj.c,v 1.00 2017/10/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bmc.h" +#include "misc/util/utilTruth.h" +#include "sat/glucose/AbcGlucose.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define MAJ_NOBJS 32 // Const0 + Const1 + nVars + nNodes + +typedef struct Maj_Man_t_ Maj_Man_t; +struct Maj_Man_t_ +{ + int nVars; // inputs + int nNodes; // internal nodes + int nObjs; // total objects (2 consts, nVars inputs, nNodes internal nodes) + int nWords; // the truth table size in 64-bit words + int iVar; // the next available SAT variable + int fUseConst; // use constant fanins + Vec_Wrd_t * vInfo; // Const0 + Const1 + nVars + nNodes + Maj(nVars) + int VarMarks[MAJ_NOBJS][3][MAJ_NOBJS]; // variable marks + int VarVals[MAJ_NOBJS+2]; // values of the first 2 + nVars variables + Vec_Wec_t * vOutLits; // output vars + bmcg_sat_solver * pSat; // SAT solver +}; + +static inline word * Maj_ManTruth( Maj_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Maj_ManValue( int iMint, int nVars ) +{ + int k, Count = 0; + for ( k = 0; k < nVars; k++ ) + Count += (iMint >> k) & 1; + return (int)(Count > nVars/2); +} +Vec_Wrd_t * Maj_ManTruthTables( Maj_Man_t * p ) +{ + Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs + 1) ); + int i, nMints = Abc_MaxInt( 64, 1 << p->nVars ); + Abc_TtFill( Maj_ManTruth(p, 1), p->nWords ); + for ( i = 0; i < p->nVars; i++ ) + Abc_TtIthVar( Maj_ManTruth(p, i+2), i, p->nVars ); + for ( i = 0; i < nMints; i++ ) + if ( Maj_ManValue(i, p->nVars) ) + Abc_TtSetBit( Maj_ManTruth(p, p->nObjs), i ); + //Dau_DsdPrintFromTruth( Maj_ManTruth(p, p->nObjs), p->nVars ); + return vInfo; +} +int Maj_ManMarkup( Maj_Man_t * p ) +{ + int i, k, j; + p->iVar = 1; + assert( p->nObjs <= MAJ_NOBJS ); + // make exception for the first node + i = p->nVars + 2; + for ( k = 0; k < 3; k++ ) + { + j = 4-k; + Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) ); + p->VarMarks[i][k][j] = p->iVar++; + } + // assign variables for other nodes + for ( i = p->nVars + 3; i < p->nObjs; i++ ) + { + for ( k = 0; k < 3; k++ ) + { + for ( j = (p->fUseConst && k == 2) ? 0 : 2; j < i - k; j++ ) + { + Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) ); + p->VarMarks[i][k][j] = p->iVar++; + } + } + } + //printf( "The number of parameter variables = %d.\n", p->iVar ); + return p->iVar; + // printout + for ( i = p->nVars + 2; i < p->nObjs; i++ ) + { + printf( "Node %d\n", i ); + for ( j = 0; j < p->nObjs; j++ ) + { + for ( k = 0; k < 3; k++ ) + printf( "%2d ", p->VarMarks[i][k][j] ); + printf( "\n" ); + } + } + return p->iVar; +} +Maj_Man_t * Maj_ManAlloc( int nVars, int nNodes, int fUseConst ) +{ + Maj_Man_t * p = ABC_CALLOC( Maj_Man_t, 1 ); + p->nVars = nVars; + p->nNodes = nNodes; + p->nObjs = 2 + nVars + nNodes; + p->fUseConst = fUseConst; + p->nWords = Abc_TtWordNum(nVars); + p->vOutLits = Vec_WecStart( p->nObjs ); + p->iVar = Maj_ManMarkup( p ); + p->VarVals[1] = 1; + p->vInfo = Maj_ManTruthTables( p ); + p->pSat = bmcg_sat_solver_start(); + bmcg_sat_solver_set_nvars( p->pSat, p->iVar ); + return p; +} +void Maj_ManFree( Maj_Man_t * p ) +{ + bmcg_sat_solver_stop( p->pSat ); + Vec_WrdFree( p->vInfo ); + Vec_WecFree( p->vOutLits ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Maj_ManFindFanin( Maj_Man_t * p, int i, int k ) +{ + int j, Count = 0, iVar = -1; + for ( j = 0; j < p->nObjs; j++ ) + if ( p->VarMarks[i][k][j] && bmcg_sat_solver_read_cex_varvalue(p->pSat, p->VarMarks[i][k][j]) ) + { + iVar = j; + Count++; + } + assert( Count == 1 ); + return iVar; +} +static inline int Maj_ManEval( Maj_Man_t * p ) +{ + int i, k, iMint; word * pFanins[3]; + for ( i = p->nVars + 2; i < p->nObjs; i++ ) + { + for ( k = 0; k < 3; k++ ) + pFanins[k] = Maj_ManTruth( p, Maj_ManFindFanin(p, i, k) ); + Abc_TtMaj( Maj_ManTruth(p, i), pFanins[0], pFanins[1], pFanins[2], p->nWords ); + } + iMint = Abc_TtFindFirstDiffBit( Maj_ManTruth(p, p->nObjs-1), Maj_ManTruth(p, p->nObjs), p->nWords ); + return iMint; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Maj_ManPrintSolution( Maj_Man_t * p ) +{ + int i, k, iVar; + printf( "Realization of %d-input majority using %d MAJ3 gates:\n", p->nVars, p->nNodes ); + for ( i = p->nVars + 2; i < p->nObjs; i++ ) + { + printf( "%02d = MAJ(", i-2 ); + for ( k = 0; k < 3; k++ ) + { + iVar = Maj_ManFindFanin( p, i, k ); + if ( iVar >= 2 && iVar < p->nVars + 2 ) + printf( " %c", 'a'+iVar-2 ); + else if ( iVar < 2 ) + printf( " %d", iVar ); + else + printf( " %02d", iVar-2 ); + } + printf( " )\n" ); + } +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Maj_ManAddCnfStart( Maj_Man_t * p ) +{ + int pLits[MAJ_NOBJS], pLits2[2], i, j, k, n, m; + // input constraints + for ( i = p->nVars + 2; i < p->nObjs; i++ ) + { + for ( k = 0; k < 3; k++ ) + { + int nLits = 0; + for ( j = 0; j < p->nObjs; j++ ) + if ( p->VarMarks[i][k][j] ) + pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 0 ); + assert( nLits > 0 ); + // input uniqueness + if ( !bmcg_sat_solver_addclause( p->pSat, pLits, nLits ) ) + return 0; + for ( n = 0; n < nLits; n++ ) + for ( m = n+1; m < nLits; m++ ) + { + pLits2[0] = Abc_LitNot(pLits[n]); + pLits2[1] = Abc_LitNot(pLits[m]); + if ( !bmcg_sat_solver_addclause( p->pSat, pLits2, 2 ) ) + return 0; + } + if ( k == 2 ) + break; + // symmetry breaking + for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] ) + for ( n = j; n < p->nObjs; n++ ) if ( p->VarMarks[i][k+1][n] ) + { + pLits2[0] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 ); + pLits2[1] = Abc_Var2Lit( p->VarMarks[i][k+1][n], 1 ); + if ( !bmcg_sat_solver_addclause( p->pSat, pLits2, 2 ) ) + return 0; + } + } + } + // outputs should be used + for ( i = 2; i < p->nObjs - 1; i++ ) + { + Vec_Int_t * vArray = Vec_WecEntry(p->vOutLits, i); + assert( Vec_IntSize(vArray) > 0 ); + if ( !bmcg_sat_solver_addclause( p->pSat, Vec_IntArray(vArray), Vec_IntSize(vArray) ) ) + return 0; + } + return 1; +} +int Maj_ManAddCnf( Maj_Man_t * p, int iMint ) +{ + // save minterm values + int i, k, n, j, Value = Maj_ManValue(iMint, p->nVars); + for ( i = 0; i < p->nVars; i++ ) + p->VarVals[i+2] = (iMint >> i) & 1; + bmcg_sat_solver_set_nvars( p->pSat, p->iVar + 4*p->nNodes ); + //printf( "Adding clauses for minterm %d.\n", iMint ); + for ( i = p->nVars + 2; i < p->nObjs; i++ ) + { + // fanin connectivity + int iBaseSatVarI = p->iVar + 4*(i - p->nVars - 2); + for ( k = 0; k < 3; k++ ) + { + int nLits2 = 0; + for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] ) + { + int iBaseSatVarJ = p->iVar + 4*(j - p->nVars - 2); + for ( n = 0; n < 2; n++ ) + { + int pLits[3], nLits = 0; + pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 ); + pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + k, n ); + if ( j >= p->nVars + 2 ) + pLits[nLits++] = Abc_Var2Lit( iBaseSatVarJ + 3, !n ); + else if ( p->VarVals[j] == n ) + continue; + if ( !bmcg_sat_solver_addclause( p->pSat, pLits, nLits ) ) + return 0; + } + } + } + // node functionality + for ( n = 0; n < 2; n++ ) + { + if ( i == p->nObjs - 1 && n == Value ) + continue; + for ( k = 0; k < 3; k++ ) + { + int pLits[3], nLits = 0; + if ( k != 0 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 0, n ); + if ( k != 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 1, n ); + if ( k != 2 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 2, n ); + if ( i != p->nObjs - 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 3, !n ); + assert( nLits <= 3 ); + if ( !bmcg_sat_solver_addclause( p->pSat, pLits, nLits ) ) + return 0; + } + } + } + p->iVar += 4*p->nNodes; + return 1; +} +void Maj_ManExactSynthesis( int nVars, int nNodes, int fUseConst, int fVerbose ) +{ + int i, iMint = 0; + abctime clkTotal = Abc_Clock(); + Maj_Man_t * p = Maj_ManAlloc( nVars, nNodes, fUseConst ); + int status = Maj_ManAddCnfStart( p ); + assert( status ); + printf( "Running exact synthesis for %d-input majority with %d MAJ3 gates...\n", p->nVars, p->nNodes ); + for ( i = 0; iMint != -1; i++ ) + { + abctime clk = Abc_Clock(); + if ( !Maj_ManAddCnf( p, iMint ) ) + break; + status = bmcg_sat_solver_solve( p->pSat, NULL, 0 ); + if ( fVerbose ) + { + printf( "Iter %3d : ", i ); + printf( "Vars = %5d ", p->iVar ); + printf( "Clauses = %5d ", bmcg_sat_solver_clausenum(p->pSat) ); + printf( "Conflicts = %7d ", bmcg_sat_solver_conflictnum(p->pSat) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + if ( status == GLUCOSE_UNSAT ) + { + printf( "The problem has no solution.\n" ); + break; + } + iMint = Maj_ManEval( p ); + } + if ( iMint == -1 ) + Maj_ManPrintSolution( p ); + Maj_ManFree( p ); + Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/sat/bmc/module.make b/src/sat/bmc/module.make index a88db8dd..94fb27cc 100644 --- a/src/sat/bmc/module.make +++ b/src/sat/bmc/module.make @@ -22,6 +22,7 @@ SRC += src/sat/bmc/bmcBCore.c \ src/sat/bmc/bmcICheck.c \ src/sat/bmc/bmcInse.c \ src/sat/bmc/bmcLoad.c \ + src/sat/bmc/bmcMaj.c \ src/sat/bmc/bmcMaxi.c \ src/sat/bmc/bmcMesh.c \ src/sat/bmc/bmcMesh2.c \ |