53static inline word * Maj3_ManTruth(
Maj3_Man_t *
p,
int v ) {
return Vec_WrdEntryP(
p->vInfo,
p->nWords * v ); }
70static inline int Maj3_ManValue(
int iMint,
int nVars )
73 for ( k = 0; k < nVars; k++ )
74 Count += (iMint >> k) & 1;
75 return (
int)(Count > nVars/2);
79 Vec_Wrd_t * vInfo =
p->vInfo = Vec_WrdStart(
p->nWords * (
p->nObjs + 1) );
80 int i, nMints = Abc_MaxInt( 64, 1 <<
p->nVars );
81 for ( i = 0; i <
p->nVars; i++ )
82 Abc_TtIthVar( Maj3_ManTruth(
p, i), i,
p->nVars );
83 for ( i = 0; i < nMints; i++ )
84 if ( Maj3_ManValue(i,
p->nVars) )
85 Abc_TtSetBit( Maj3_ManTruth(
p,
p->nObjs), i );
91 int i, k, Entry, Obj = 0;
93 for ( k = 0; k < nVars; k++ )
95 Vec_IntReverseOrder( vLevels );
99 for ( k = 0; k < Entry; k++ )
102 Vec_IntReverseOrder( vLevels );
108 int nLevels = Vec_IntSize(
p->vLevels);
109 int nSecond = Vec_IntEntry(
p->vLevels, 1);
111 assert( Vec_IntEntry(
p->vLevels, 0) == 1 );
113 assert(
p->nNodes == Vec_IntSum(
p->vLevels) );
116 for ( i = 0; i <
p->nObjs; i++ )
117 for ( k = 0; k <
p->nObjs; k++ )
118 p->VarMarks[i][k] = -1;
119 for ( k = 0; k < 3; k++ )
120 p->VarMarks[
p->nVars][k] = 1;
121 for ( k = 0; k < nSecond; k++ )
122 p->VarMarks[
p->nObjs-1][
p->nObjs-2-k] = 1;
123 for ( k = 2; k < nLevels; k++ )
124 p->VarMarks[Firsts[k]][Firsts[k-1]] = 1;
125 for ( i =
p->nVars+1; i < (nSecond == 3 ?
p->nObjs-1 :
p->nObjs); i++ )
126 for ( k = 0; k < Firsts[Levels[i]]; k++ )
127 if (
p->VarMarks[i][k] == -1 )
128 p->VarMarks[i][k] = nSatVars++;
137 printf(
"Variable map for problem with %d inputs, %d nodes and %d levels: ",
p->nVars,
p->nNodes, Vec_IntSize(
p->vLevels) );
138 Vec_IntPrint(
p->vLevels );
141 for ( i = 0; i <
p->nObjs; i++ )
144 for ( i =
p->nObjs-1; i >=
p->nVars; i-- )
146 printf(
" %2d ", i );
147 printf(
" %2d ", Levels[i] );
148 for ( k = 0; k <
p->nObjs; k++ )
149 if (
p->VarMarks[i][k] == -1 )
151 else if (
p->VarMarks[i][k] == 1 )
170static inline int Maj3_ManFindFanin(
Maj3_Man_t *
p,
int i,
int * pFanins )
173 p->nLits[0] =
p->nLits[1] =
p->nLits[2] = 0;
174 for ( f = 0; f < i; f++ )
176 if (
p->VarMarks[i][f] < 0 )
178 assert(
p->VarMarks[i][f] > 0 );
179 if (
p->VarMarks[i][f] == 1 )
182 pFanins[nFanins++] = f;
186 p->pLits[1][
p->nLits[1]++] = Abc_Var2Lit(
p->VarMarks[i][f], 1);
187 pFanins[nFanins++] = f;
190 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit(
p->VarMarks[i][f], 0);
194static inline void Maj3_ManPrintSolution(
Maj3_Man_t *
p )
196 int i, k, iVar, nFanins, pFanins[
MAJ3_OBJS];
197 printf(
"Realization of %d-input majority using %d MAJ3 gates:\n",
p->nVars,
p->nNodes );
199 for ( i =
p->nObjs - 1; i >=
p->nVars; i-- )
201 printf(
"%02d = MAJ(", i );
202 nFanins = Maj3_ManFindFanin(
p, i, pFanins );
204 for ( k = 0; k < 3; k++ )
207 if ( iVar >= 0 && iVar < p->nVars )
208 printf(
" %c",
'a'+iVar );
210 printf(
" %02d", iVar );
219 int i, k, iMint, pFanins[3];
word * pFaninsW[3];
220 for ( i =
p->nVars; i < p->nObjs; i++ )
222 int nFanins = Maj3_ManFindFanin(
p, i, pFanins );
224 for ( k = 0; k < 3; k++ )
225 pFaninsW[k] = Maj3_ManTruth(
p, pFanins[k] );
226 Abc_TtMaj( Maj3_ManTruth(
p, i), pFaninsW[0], pFaninsW[1], pFaninsW[2],
p->nWords );
231 for ( i = 0; i < (1 <<
p->nVars); i++ )
233 int nOnes = Abc_TtBitCount16(i);
234 if ( nOnes < p->nVars/2 || nOnes >
p->nVars/2+1 )
236 if ( Abc_TtGetBit(Maj3_ManTruth(
p,
p->nObjs), i) == Abc_TtGetBit(Maj3_ManTruth(
p,
p->nObjs-1), i) )
244 if ( Flag &&
p->nVars >= 6 )
245 iMint = Abc_TtFindLastDiffBit( Maj3_ManTruth(
p,
p->nObjs-1), Maj3_ManTruth(
p,
p->nObjs),
p->nVars );
247 iMint = Abc_TtFindFirstDiffBit( Maj3_ManTruth(
p,
p->nObjs-1), Maj3_ManTruth(
p,
p->nObjs),
p->nVars );
250 assert( iMint < (1 <<
p->nVars) );
269 for ( i = 0; i < nLits; i++ )
270 printf(
"%c%d ", Abc_LitIsCompl(pLits[i]) ?
'-' :
'+', Abc_Lit2Var(pLits[i]) );
275 int i, k, status, nLits, pLits[
MAJ3_OBJS];
278 for ( i =
p->nVars; i < p->nObjs; i++ )
282 for ( k = 0; k <
p->nObjs; k++ )
283 Count +=
p->VarMarks[i][k] == 1;
289 for ( k = 0; k <
p->nObjs; k++ )
290 if (
p->VarMarks[i][k] > 1 )
291 pLits[nLits++] = Abc_Var2Lit(
p->VarMarks[i][k], 0 );
299 for ( k = 0; k <
p->nObjs-1; k++ )
303 for ( i = 0; i <
p->nObjs; i++ )
304 Count +=
p->VarMarks[i][k] == 1;
310 for ( i = 0; i <
p->nObjs; i++ )
311 if (
p->VarMarks[i][k] > 1 )
312 pLits[nLits++] = Abc_Var2Lit(
p->VarMarks[i][k], 0 );
326 int i, k, j, n, * pVals =
p->ObjVals;
327 for ( i = 0; i <
p->nVars; i++ )
328 pVals[i] = (iMint >> i) & 1;
330 pVals[
p->nVars] = (pVals[0] && pVals[1]) || (pVals[0] && pVals[2]) || (pVals[1] && pVals[2]);
332 pVals[
p->nObjs-1] = Maj3_ManValue(iMint,
p->nVars);
334 for ( i =
p->nVars + 1; i < p->nObjs - 1; i++ )
335 pVals[i] =
p->iVar++;
338 for ( n = 0; n < 2; n++ )
339 for ( i =
p->nVars + 1; i < p->nObjs; i++ )
342 for ( k = 0; k <
p->nObjs; k++ )
if (
p->VarMarks[i][k] >= 1 )
345 int pLits[5], nLits = 0;
346 if ( pVals[k] == !n )
349 pLits[nLits++] = Abc_Var2Lit( pVals[k], n );
350 if (
p->VarMarks[i][k] > 1 )
351 pLits[nLits++] = Abc_Var2Lit(
p->VarMarks[i][k], 1 );
352 for ( j = k+1; j <
p->nObjs; j++ )
if (
p->VarMarks[i][j] >= 1 )
356 if ( pVals[j] == !n )
359 pLits[nLits2++] = Abc_Var2Lit( pVals[j], n );
360 if (
p->VarMarks[i][j] > 1 )
361 pLits[nLits2++] = Abc_Var2Lit(
p->VarMarks[i][j], 1 );
366 pLits[nLits2++] = Abc_Var2Lit( pVals[i], !n );
367 assert( nLits2 > 0 && nLits2 <= 5 );
380 for ( i =
p->nVars+1; i < p->nObjs; i++ )
382 int nFanins = Maj3_ManFindFanin(
p, i, pFanins );
394 else if ( nFanins > 3 )
396 int nLits = Abc_MinInt(4 -
p->nLits[2],
p->nLits[1]);
420 p->vLevels = vLevels;
423 p->nObjs = nVars + nNodes;
424 p->nWords = Abc_TtWordNum(nVars);
435 Vec_WrdFree(
p->vInfo );
453 int i, status, nLazy, nLazyAll = 0, iMint = 0;
454 printf(
"Running exact synthesis for %d-input majority with %d MAJ3 gates...\n", nVars, nNodes );
456 for ( i = 0; iMint != -1; i++ )
466 printf(
"Became UNSAT after adding lazy constraints.\n" );
477 printf(
"Iter %3d : ", i );
479 printf(
" Var =%5d ",
p->iVar );
482 printf(
"Lazy =%9d ", nLazyAll );
483 Abc_PrintTime( 1,
"Time", Abc_Clock() - clk );
487 printf(
"The problem has no solution.\n" );
490 iMint = Maj3_ManEval(
p );
493 Maj3_ManPrintSolution(
p );
495 Abc_PrintTime( 1,
"Total runtime", Abc_Clock() - clkTotal );
576static inline word * Zyx_ManTruth(
Zyx_Man_t *
p,
int v ) {
return Vec_WrdEntryP(
p->vInfo,
p->nWords * v ); }
578static inline int Zyx_FuncVar(
Zyx_Man_t *
p,
int i,
int m ) {
return (
p->LutMask + 1) * (i -
p->pPars->nVars) + m; }
579static inline int Zyx_TopoVar(
Zyx_Man_t *
p,
int i,
int f ) {
return p->TopoBase +
p->nObjs * (i -
p->pPars->nVars) + f; }
580static inline int Zyx_MintVar(
Zyx_Man_t *
p,
int m,
int i ) {
return p->MintBase +
p->nObjs * m + i; }
584static inline int Zyx_ManIsUsed2(
Zyx_Man_t *
p,
int m,
int n,
int i,
int j )
586 int Pos = ((m *
p->pPars->nNodes + n -
p->pPars->nVars) *
p->nObjs + i) *
p->nObjs + j;
588 assert( i < n && j < n && i < j );
589 if ( Vec_BitEntry(
p->vUsed2,
Pos) )
592 Vec_BitWriteEntry(
p->vUsed2,
Pos, 1 );
596static inline int Zyx_ManIsUsed3(
Zyx_Man_t *
p,
int m,
int n,
int i,
int j,
int k )
598 int Pos = (((m *
p->pPars->nNodes + n -
p->pPars->nVars) *
p->nObjs + i) *
p->nObjs + j) *
p->nObjs + k;
600 assert( i < n && j < n && k < n && i < j && j < k );
601 if ( Vec_BitEntry(
p->vUsed3,
Pos) )
604 Vec_BitWriteEntry(
p->vUsed3,
Pos, 1 );
621 int iLit = Abc_Var2Lit(
Var, !Value );
624 assert( Vec_IntEntry(
p->vVarValues,
Var) == -1 );
625 Vec_IntWriteEntry(
p->vVarValues,
Var, Value );
631 word * pSpec =
p->pPars->fMajority ? Zyx_ManTruth(
p,
p->nObjs) :
p->pTruth;
633 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
636 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
637 for ( k = i; k <
p->nObjs; k++ )
642 if (
p->pPars->fMajority )
643 for ( k = 0; k <
p->pPars->nVars; k++ )
646 for ( m = 0; m < (1 <<
p->pPars->nVars); m++ )
648 for ( i = 0; i <
p->pPars->nVars; i++ )
658 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
661 for ( k = 0; k < i; k++ )
662 pLits[nLits++] = Abc_Var2Lit( Zyx_TopoVar(
p, i, k), 0 );
669 for ( k = 0; k <
p->nObjs-1; k++ )
672 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
673 pLits[nLits++] = Abc_Var2Lit( Zyx_TopoVar(
p, i, k), 0 );
680 if (
p->pPars->nLutSize != 2 )
682 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
684 for ( k = 0; k < 3; k++ )
686 pLits[0] = Abc_Var2Lit( Zyx_FuncVar(
p, i, 1), k==1 );
687 pLits[1] = Abc_Var2Lit( Zyx_FuncVar(
p, i, 2), k==2 );
688 pLits[2] = Abc_Var2Lit( Zyx_FuncVar(
p, i, 3), k!=0 );
692 if (
p->pPars->fOnlyAnd )
694 pLits[0] = Abc_Var2Lit( Zyx_FuncVar(
p, i, 1), 1 );
695 pLits[1] = Abc_Var2Lit( Zyx_FuncVar(
p, i, 2), 1 );
696 pLits[2] = Abc_Var2Lit( Zyx_FuncVar(
p, i, 3), 0 );
705 int i, k, nTopoVars = 0;
707 for ( k = 0; k <
p->nObjs-1; k++ )
710 for ( i =
p->nObjs-1; i >=
p->pPars->nVars; i-- )
713 for ( k = 0; k <
p->nObjs-1; k++ )
715 int iVar = Zyx_TopoVar(
p, i, k);
716 if ( Vec_IntEntry(
p->vVarValues, iVar) == -1 )
719 printf(
"%3d ", Vec_IntEntry(
p->vVarValues, iVar) );
724 printf(
"Using %d active functionality vars and %d active topology vars (out of %d SAT vars).\n",
730 for ( i = 0; i < nLits; i++ )
731 printf(
"%c%d ", Abc_LitIsCompl(pLits[i]) ?
'-' :
'+', Abc_Lit2Var(pLits[i]) );
746static inline int Zyx_ManValue(
int iMint,
int nVars )
749 for ( k = 0; k < nVars; k++ )
750 Count += (iMint >> k) & 1;
751 return (
int)(Count > nVars/2);
755 Vec_Wrd_t * vInfo =
p->vInfo = Vec_WrdStart(
p->nWords * (
p->nObjs + 1) );
756 int i, nMints = Abc_MaxInt( 64, 1 <<
p->pPars->nVars );
757 assert(
p->pPars->fMajority == (pTruth == NULL) );
758 for ( i = 0; i <
p->pPars->nVars; i++ )
759 Abc_TtIthVar( Zyx_ManTruth(
p, i), i,
p->pPars->nVars );
760 if (
p->pPars->fMajority )
762 for ( i = 0; i < nMints; i++ )
763 if ( Zyx_ManValue(i,
p->pPars->nVars) )
764 Abc_TtSetBit( Zyx_ManTruth(
p,
p->nObjs), i );
765 for ( i = 0; i < nMints; i++ )
766 if ( Abc_TtBitCount16(i) ==
p->pPars->nVars/2 || Abc_TtBitCount16(i) ==
p->pPars->nVars/2+1 )
767 Vec_IntPush(
p->vMidMints, i );
774 Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
775 int i, k,
nWords = Abc_TtWordNum(nVars);
776 word Cof0[64], Cof1[64];
777 word Cof01[64], Cof10[64];
779 for ( i = 0; i < nVars; i++ )
781 Abc_TtCofactor0p( Cof0, pTruth,
nWords, i );
782 Abc_TtCofactor1p( Cof1, pTruth,
nWords, i );
783 for ( k = i+1; k < nVars; k++ )
785 Abc_TtCofactor1p( Cof01, Cof0,
nWords, k );
786 Abc_TtCofactor0p( Cof10, Cof1,
nWords, k );
787 if ( Abc_TtEqual( Cof01, Cof10,
nWords ) )
788 Vec_IntPushTwo( vPairs, i, k );
798 p->nObjs =
p->pPars->nVars +
p->pPars->nNodes;
799 p->nWords = Abc_TtWordNum(
p->pPars->nVars);
800 p->LutMask = (1 <<
p->pPars->nLutSize) - 1;
801 p->TopoBase = (1 <<
p->pPars->nLutSize) *
p->pPars->nNodes;
802 p->MintBase =
p->TopoBase +
p->pPars->nNodes *
p->nObjs;
803 p->vVarValues = Vec_IntStartFull(
p->MintBase + (1 <<
p->pPars->nVars) *
p->nObjs );
804 p->vMidMints = Vec_IntAlloc( 1 <<
p->pPars->nVars );
808 if ( pPars->fUseIncr )
810 if (
p->pPars->nLutSize == 2 ||
p->pPars->fMajority )
811 p->vUsed2 = Vec_BitStart( (1 <<
p->pPars->nVars) *
p->pPars->nNodes *
p->nObjs *
p->nObjs );
812 else if (
p->pPars->nLutSize == 3 )
813 p->vUsed3 = Vec_BitStart( (1 <<
p->pPars->nVars) *
p->pPars->nNodes *
p->nObjs *
p->nObjs *
p->nObjs );
824 Vec_WrdFree(
p->vInfo );
825 Vec_BitFreeP( &
p->vUsed2 );
826 Vec_BitFreeP( &
p->vUsed3 );
827 Vec_IntFree(
p->vPairs );
828 Vec_IntFree(
p->vMidMints );
829 Vec_IntFree(
p->vVarValues );
847 assert( i >=
p->pPars->nVars && i < p->nObjs );
848 p->nLits[0] =
p->nLits[1] = 0;
849 for ( k = 0; k < i; k++ )
852 p->pFanins[i][
p->nLits[1]] = k;
853 p->pLits[Val][
p->nLits[Val]++] = Abc_Var2Lit(Zyx_TopoVar(
p, i, k), Val);
859 int i, k, j, Entry[2], Node[2], nLazy = 0;
862 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
865 if ( nFanins ==
p->pPars->nLutSize )
868 assert( nFanins ==
p->nLits[1] );
869 if (
p->nLits[1] >
p->pPars->nLutSize )
871 p->nLits[1] =
p->pPars->nLutSize + 1;
883 if ( nLazy || !
p->pPars->fOrderNodes )
886 for ( i =
p->pPars->nVars + 1; i < p->nObjs; i++ )
888 for ( k =
p->pPars->nLutSize - 1; k >= 0; k-- )
889 if (
p->pFanins[i-1][k] !=
p->pFanins[i][k] )
893 if (
p->pPars->fMajority )
896 for ( k =
p->LutMask; k >= 0; k-- )
913 for ( j =
p->LutMask; j >= k; j-- )
917 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit(Zyx_FuncVar(
p, i-1, j), ValA );
918 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit(Zyx_FuncVar(
p, i, j), ValB );
924 if (
p->pFanins[i-1][k] <
p->pFanins[i][k] )
935 for ( j =
p->pFanins[i-1][k]; j < p->nObjs-1; j++ )
939 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(
p, i-1, j), ValA );
940 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(
p, i, j), ValB );
952 assert( Entry[0] < Entry[1] );
953 for ( j = 0; j < 2; j++ )
956 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
962 assert( Node[j] >=
p->pPars->nVars );
965 if ( Node[0] <= Node[1] )
967 assert( Node[0] > Node[1] );
974 for ( j =
p->pPars->nVars; j <= Node[1]; j++ )
978 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(
p, j, Entry[0]), ValA );
979 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(
p, j, Entry[1]), ValB );
988 Vec_Int_t * vLits = Vec_IntAlloc( 100 );
int i, k;
989 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
992 assert( nFanins ==
p->pPars->nLutSize );
993 for ( k = 0; k <
p->pPars->nLutSize; k++ )
994 Vec_IntPush( vLits, Abc_Var2Lit(Zyx_TopoVar(
p, i,
p->pFanins[i][k]), 1) );
1000 Vec_IntFree( vLits );
1006 assert( !
p->pPars->fMajority ||
p->pPars->nLutSize == 3 );
1009 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
1012 assert( nFanins ==
p->pPars->nLutSize );
1013 if (
p->pPars->fMajority )
1015 int Sets[3][2] = {{0, 1}, {0, 2}, {1, 2}};
1016 for ( k = 0; k < 3; k++ )
1018 if ( Zyx_ManIsUsed2(
p, iMint, i,
p->pFanins[i][Sets[k][0]],
p->pFanins[i][Sets[k][1]]) )
1020 for ( n = 0; n < 2; n++ )
1023 for ( s = 0; s < 2; s++ )
1025 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(
p, i,
p->pFanins[i][Sets[k][s]]), 1 );
1026 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint,
p->pFanins[i][Sets[k][s]]), n );
1028 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint, i), !n );
1036 if (
p->pPars->nLutSize == 2 && Zyx_ManIsUsed2(
p, iMint, i,
p->pFanins[i][0],
p->pFanins[i][1]) )
1038 if (
p->pPars->nLutSize == 3 && Zyx_ManIsUsed3(
p, iMint, i,
p->pFanins[i][0],
p->pFanins[i][1],
p->pFanins[i][2]) )
1040 for ( k = 0; k <=
p->LutMask; k++ )
1041 for ( n = 0; n < 2; n++ )
1044 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_FuncVar(
p, i, k), n );
1045 for ( j = 0; j <
p->pPars->nLutSize; j++ )
1047 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(
p, i,
p->pFanins[i][j]), 1 );
1048 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint,
p->pFanins[i][j]), (k >> j) & 1 );
1050 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint, i), !n );
1061 int i, k, n, j, s, t, u;
1063 assert( !
p->pPars->fMajority &&
p->pPars->nLutSize < 4 );
1065 if (
p->pPars->nLutSize == 2 )
1067 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
1068 for ( s = 0; s < i; s++ )
1069 for ( t = s+1; t < i; t++ )
1071 p->pFanins[i][0] = s;
1072 p->pFanins[i][1] = t;
1073 for ( k = 0; k <=
p->LutMask; k++ )
1074 for ( n = 0; n < 2; n++ )
1077 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_FuncVar(
p, i, k), n );
1078 for ( j = 0; j <
p->pPars->nLutSize; j++ )
1080 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(
p, i,
p->pFanins[i][j]), 1 );
1081 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint,
p->pFanins[i][j]), (k >> j) & 1 );
1083 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint, i), !n );
1089 else if (
p->pPars->nLutSize == 3 )
1091 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
1092 for ( s = 0; s < i; s++ )
1093 for ( t = s+1; t < i; t++ )
1094 for ( u = t+1; u < i; u++ )
1096 p->pFanins[i][0] = s;
1097 p->pFanins[i][1] = t;
1098 p->pFanins[i][2] = u;
1099 for ( k = 0; k <=
p->LutMask; k++ )
1100 for ( n = 0; n < 2; n++ )
1103 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_FuncVar(
p, i, k), n );
1104 for ( j = 0; j <
p->pPars->nLutSize; j++ )
1106 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(
p, i,
p->pFanins[i][j]), 1 );
1107 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint,
p->pFanins[i][j]), (k >> j) & 1 );
1109 p->pLits[0][
p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(
p, iMint, i), !n );
1129static void Zyx_ManPrintSolutionFile(
Zyx_Man_t *
p,
int fCompl,
int fFirst )
1132 char FileName[1000];
int i, k;
1133 if ( fCompl ) Abc_TtNot(
p->pTruth, Abc_TtWordNum(
p->pPars->nVars) );
1134 Abc_TtWriteHexRev( FileName,
p->pTruth,
p->pPars->nVars );
1135 if ( fCompl ) Abc_TtNot(
p->pTruth, Abc_TtWordNum(
p->pPars->nVars) );
1136 sprintf( FileName + (1 << (
p->pPars->nVars-2)),
"-%d-%d.bool",
p->pPars->nLutSize,
p->pPars->nNodes );
1137 pFile = fopen( FileName, fFirst ?
"wb" :
"ab" );
1138 if ( pFile == NULL )
1140 printf(
"Cannot open input file \"%s\".\n", FileName );
1143 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
1145 fprintf( pFile,
"%c",
'A' + i );
1146 if (
p->pPars->fMajority )
1147 fprintf( pFile,
"maj3" );
1150 for ( k =
p->LutMask; k >= 0; k-- )
1152 for ( k = 0; k < i; k++ )
1155 if ( k >= 0 && k < p->pPars->nVars )
1156 fprintf( pFile,
"%c",
'a' + k );
1158 fprintf( pFile,
"%c",
'A' + k );
1161 fprintf( pFile,
"\n" );
1163 fprintf( pFile,
"\n" );
1165 printf(
"Dumped solution into file \"%s\".\n", FileName );
1167static void Zyx_ManPrintSolution(
Zyx_Man_t *
p,
int fCompl,
int fFirst )
1170 printf(
"Realization of given %d-input function using %d %d-input %s:\n",
1171 p->pPars->nVars,
p->pPars->nNodes,
p->pPars->nLutSize,
p->pPars->fMajority ?
"MAJ-gates" :
"LUTs" );
1172 for ( i =
p->nObjs - 1; i >=
p->pPars->nVars; i-- )
1174 printf(
"%02d = ", i );
1175 if (
p->pPars->fMajority )
1179 printf(
"%d\'b", 1 <<
p->pPars->nLutSize );
1180 for ( k =
p->LutMask; k >= 0; k-- )
1184 for ( k = 0; k < i; k++ )
1187 if ( k >= 0 && k < p->pPars->nVars )
1188 printf(
" %c",
'a'+k );
1190 printf(
" %02d", k );
1194 if ( !
p->pPars->fMajority )
1195 Zyx_ManPrintSolutionFile(
p, fCompl, fFirst );
1197static inline int Zyx_ManEval(
Zyx_Man_t *
p )
1199 static int Flag = 0;
1201 int i, k, j, iMint;
word * pFaninsW[6], * pSpec;
1202 for ( i =
p->pPars->nVars; i < p->nObjs; i++ )
1205 assert( nFanins ==
p->pPars->nLutSize );
1206 for ( k = 0; k <
p->pPars->nLutSize; k++ )
1207 pFaninsW[k] = Zyx_ManTruth(
p,
p->pFanins[i][k] );
1208 if (
p->pPars->fMajority )
1209 Abc_TtMaj( Zyx_ManTruth(
p, i), pFaninsW[0], pFaninsW[1], pFaninsW[2],
p->nWords );
1212 Abc_TtConst0( Zyx_ManTruth(
p, i),
p->nWords );
1213 for ( k = 1; k <=
p->LutMask; k++ )
1216 Abc_TtConst1( Zyx_ManTruth(
p,
p->nObjs),
p->nWords );
1217 for ( j = 0; j <
p->pPars->nLutSize; j++ )
1218 Abc_TtAndCompl( Zyx_ManTruth(
p,
p->nObjs), Zyx_ManTruth(
p,
p->nObjs), 0, pFaninsW[j], !((k >> j) & 1),
p->nWords );
1219 Abc_TtOr( Zyx_ManTruth(
p, i), Zyx_ManTruth(
p, i), Zyx_ManTruth(
p,
p->nObjs),
p->nWords );
1223 pSpec =
p->pPars->fMajority ? Zyx_ManTruth(
p,
p->nObjs) :
p->pTruth;
1224 if (
p->pPars->fMajority )
1227 if ( Abc_TtGetBit(pSpec, iMint) != Abc_TtGetBit(Zyx_ManTruth(
p,
p->nObjs-1), iMint) )
1233 if ( Flag &&
p->pPars->nVars >= 6 )
1234 iMint = Abc_TtFindLastDiffBit( Zyx_ManTruth(
p,
p->nObjs-1), pSpec,
p->pPars->nVars );
1236 iMint = Abc_TtFindFirstDiffBit( Zyx_ManTruth(
p,
p->nObjs-1), pSpec,
p->pPars->nVars );
1239 assert( iMint < (1 <<
p->pPars->nVars) );
1243static inline void Zyx_ManEvalStats(
Zyx_Man_t *
p )
1246 for ( i = 0; i < (1 <<
p->pPars->nVars); i++ )
1247 printf(
"%d=%d ", i,
p->Counts[i] );
1250static inline void Zyx_ManPrint(
Zyx_Man_t *
p,
int Iter,
int iMint,
int nLazyAll,
abctime clk )
1252 printf(
"Iter %6d : ", Iter );
1256 printf(
"Lazy =%6d ", nLazyAll );
1258 Abc_PrintTime( 1,
"Time", clk );
1264 int status, Iter, iMint = 0, fCompl = 0, nLazyAll = 0, nSols = 0;
1267 if ( !pPars->fMajority )
1269 Abc_TtReadHex( pTruth, pPars->pTtStr );
1270 if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, Abc_TtWordNum(pPars->nVars) ); }
1272 assert( pPars->nVars <= 10 );
1273 assert( pPars->nLutSize <= 6 );
1274 p =
Zyx_ManAlloc( pPars, pPars->fMajority ? NULL : pTruth );
1275 printf(
"Running exact synthesis for %d-input function with %d %d-input %s...\n",
1276 p->pPars->nVars,
p->pPars->nNodes,
p->pPars->nLutSize,
p->pPars->fMajority ?
"MAJ-gates" :
"LUTs" );
1277 for ( Iter = 0 ; ; Iter++ )
1284 printf(
"Became UNSAT after adding lazy constraints.\n" );
1296 iMint = Zyx_ManEval(
p );
1299 if ( pPars->fEnumSols )
1302 if ( pPars->fVerbose )
1304 Zyx_ManPrint(
p, Iter, iMint, nLazyAll, Abc_Clock() - clkTotal );
1307 Zyx_ManPrintSolution(
p, fCompl, nSols==1 );
1320 printf(
"Became UNSAT after adding constraints for minterm %d\n", iMint );
1325 if ( pPars->fVerbose && (!pPars->fUseIncr || Iter % 100 == 0) )
1327 Zyx_ManPrint(
p, Iter, iMint, nLazyAll, Abc_Clock() - clk );
1333 if ( pPars->fVerbose )
1334 Zyx_ManPrint(
p, Iter, iMint, nLazyAll, Abc_Clock() - clkTotal );
1335 if ( pPars->fEnumSols )
1336 printf(
"Finished enumerating %d solutions.\n", nSols );
1337 else if ( iMint == -1 )
1338 Zyx_ManPrintSolution(
p, fCompl, 1 );
1340 printf(
"The problem has no solution.\n" );
1342 printf(
"Added = %d. Tried = %d. ",
p->nUsed[1],
p->nUsed[0] );
1343 Abc_PrintTime( 1,
"Total runtime", Abc_Clock() - clkTotal );
1362 char Symb, * pCur, * pBuffer = Abc_UtilStrsav( pFileName );
1364 for ( pCur = pBuffer; *pCur; pCur++ )
1365 if ( !Abc_TtIsHexDigit(*pCur) )
1367 Symb = *pCur; *pCur = 0;
1368 nLength = (int)
strlen(pBuffer);
1371 else if ( nLength == 2 )
1373 else if ( nLength == 4 )
1375 else if ( nLength == 8 )
1377 else if ( nLength == 16 )
1379 else if ( nLength == 32 )
1381 else if ( nLength == 64 )
1386 printf(
"Invalid truth table size.\n" );
1389 Abc_TtReadHex( pTruth, pBuffer );
1392 while ( *pCur && *pCur++ !=
'-' );
1396 printf(
"Expecting \'-\' after truth table before LUT size.\n" );
1400 *nLutSize = atoi(pCur);
1401 while ( *pCur && *pCur++ !=
'-' );
1405 printf(
"Expecting \'-\' after LUT size before node count.\n" );
1408 *nNodes = atoi(pCur);
1417 int i,
nWords = Abc_TtWordNum(nVars);
1419 for ( i = 0; i < nVars; i++ )
1420 Abc_TtIthVar( Zyx_TestTruth(vInfo, i,
nWords), i, nVars );
1426 int k, j,
nWords = Abc_TtWordNum(nVars);
1427 word * pFaninsW[6];
char * pTruth, * pFanins;
1428 word * pThis, * pLast = Zyx_TestTruth( vTruths, Vec_WrdSize(vTruths)/
nWords - 1,
nWords );
1429 if ( pLine[
strlen(pLine)-1] ==
'\n' ) pLine[
strlen(pLine)-1] = 0;
1430 if ( pLine[
strlen(pLine)-1] ==
'\r' ) pLine[
strlen(pLine)-1] = 0;
1431 if ( pLine[0] == 0 )
1433 if ( (
int)
strlen(pLine) != 1 + nLutSize + (1 << nLutSize) )
1435 printf(
"Node representation has %d chars (expecting %d chars).\n", (
int)
strlen(pLine), 1 + nLutSize + (1 << nLutSize) );
1438 if ( pLine[0] !=
'A' + iObj )
1440 printf(
"The output node in line %s is not correct.\n", pLine );
1444 pFanins = pTruth + (1 << nLutSize);
1445 for ( k = nLutSize - 1; k >= 0; k-- )
1446 pFaninsW[k] = Zyx_TestTruth( vTruths, pFanins[k] >=
'a' ? pFanins[k] -
'a' : pFanins[k] -
'A',
nWords );
1447 pThis = Zyx_TestTruth(vTruths, iObj,
nWords);
1448 Abc_TtConst0( pThis,
nWords );
1449 for ( k = 0; k < (1 << nLutSize); k++ )
1451 if ( pTruth[(1 << nLutSize) - 1 - k] ==
'0' )
1453 Abc_TtConst1( pLast,
nWords );
1454 for ( j = 0; j < nLutSize; j++ )
1455 Abc_TtAndCompl( pLast, pLast, 0, pFaninsW[j], !((k >> j) & 1),
nWords );
1456 Abc_TtOr( pThis, pThis, pLast,
nWords );
1463 int iObj, nStrs = 0, nVars = -1, nLutSize = -1, nNodes = -1;
1465 FILE * pFile = fopen( pFileName,
"rb" );
1466 if ( pFile == NULL )
1468 printf(
"Cannot open input file \"%s\".\n", pFileName );
1475 printf(
"This tester does not support functions with more than 8 inputs.\n" );
1480 printf(
"This tester does not support nodes with more than 6 inputs.\n" );
1485 printf(
"This tester does not support structures with more than 16 inputs.\n" );
1489 for ( iObj = nVars; fgets(Line, 1000, pFile) != NULL; iObj++ )
1493 if ( iObj != nVars + nNodes )
1495 printf(
"The number of nodes in the structure is not correct.\n" );
1499 pImpl = Zyx_TestTruth( vInfo, iObj-1, Abc_TtWordNum(nVars) );
1500 if ( Abc_TtEqual( pImpl, pSpec, Abc_TtWordNum(nVars) ) )
1501 printf(
"Structure %3d : Verification successful.\n", nStrs );
1504 printf(
"Structure %3d : Verification FAILED.\n", nStrs );
1510 Vec_WrdFree( vInfo );
int bmcg_sat_solver_conflictnum(bmcg_sat_solver *s)
int bmcg_sat_solver_varnum(bmcg_sat_solver *s)
bmcg_sat_solver * bmcg_sat_solver_start()
MACRO DEFINITIONS ///.
int bmcg_sat_solver_solve(bmcg_sat_solver *s, int *plits, int nlits)
int bmcg_sat_solver_addclause(bmcg_sat_solver *s, int *plits, int nlits)
int bmcg_sat_solver_read_cex_varvalue(bmcg_sat_solver *s, int ivar)
void bmcg_sat_solver_set_nvars(bmcg_sat_solver *s, int nvars)
int bmcg_sat_solver_clausenum(bmcg_sat_solver *s)
void bmcg_sat_solver_stop(bmcg_sat_solver *s)
#define GLUCOSE_UNSAT
INCLUDES ///.
#define ABC_CALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
int Zyx_TestReadNode(char *pLine, Vec_Wrd_t *vTruths, int nVars, int nLutSize, int iObj)
int Maj3_ManAddCnfStart(Maj3_Man_t *p)
int Maj3_ManMarkup(Maj3_Man_t *p)
void Zyx_SetConstVar(Zyx_Man_t *p, int Var, int Value)
void Zyx_ManExactSynthesis(Bmc_EsPar_t *pPars)
struct Maj3_Man_t_ Maj3_Man_t
int Zyx_ManAddCnfBlockSolution(Zyx_Man_t *p)
void Zyx_ManPrintVarMap(Zyx_Man_t *p, int fSat)
void Zyx_ManFree(Zyx_Man_t *p)
int Zyx_ManAddCnfLazyFunc2(Zyx_Man_t *p, int iMint)
#define MAJ3_OBJS
DECLARATIONS ///.
void Zyx_ManSetupVars(Zyx_Man_t *p)
Vec_Wrd_t * Zyx_TestCreateTruthTables(int nVars, int nNodes)
void Maj3_PrintClause(int *pLits, int nLits)
int Zyx_ManAddCnfStart(Zyx_Man_t *p)
int Zyx_ManCollectFanins(Zyx_Man_t *p, int i)
int Zyx_TestGetTruthTablePars(char *pFileName, word *pTruth, int *nVars, int *nLutSize, int *nNodes)
void Zyx_TestExact(char *pFileName)
int Maj3_ManAddConstraintsLazy(Maj3_Man_t *p)
Vec_Wrd_t * Maj3_ManTruthTables(Maj3_Man_t *p)
struct Zyx_Man_t_ Zyx_Man_t
int Maj3_ManAddCnf(Maj3_Man_t *p, int iMint)
void Zyx_PrintClause(int *pLits, int nLits)
Vec_Int_t * Zyx_ManCreateSymVarPairs(word *pTruth, int nVars)
int Zyx_ManAddCnfLazyTopo(Zyx_Man_t *p)
void Maj3_ManVarMapPrint(Maj3_Man_t *p)
int Zyx_ManAddCnfLazyFunc(Zyx_Man_t *p, int iMint)
void Maj3_ManFirstAndLevel(Vec_Int_t *vLevels, int Firsts[MAJ3_OBJS], int Levels[MAJ3_OBJS], int nVars, int nObjs)
Vec_Wrd_t * Zyx_ManTruthTables(Zyx_Man_t *p, word *pTruth)
int Maj3_ManExactSynthesis(int nVars, int nNodes, int fVerbose, Vec_Int_t *vLevels)
void Maj3_ManFree(Maj3_Man_t *p)
Zyx_Man_t * Zyx_ManAlloc(Bmc_EsPar_t *pPars, word *pTruth)
Maj3_Man_t * Maj3_ManAlloc(int nVars, int nNodes, Vec_Int_t *vLevels)
typedefABC_NAMESPACE_HEADER_START struct Bmc_EsPar_t_ Bmc_EsPar_t
INCLUDES ///.
void Dau_DsdPrintFromTruth(word *pTruth, int nVarsInit)
void Extra_PrintBinary(FILE *pFile, unsigned Sign[], int nBits)
unsigned __int64 word
DECLARATIONS ///.
int VarMarks[MAJ3_OBJS][MAJ3_OBJS]
int pLits[2][2 *MAJ3_OBJS]
int pFanins[MAJ3_OBJS][MAJ3_OBJS]
typedefABC_NAMESPACE_HEADER_START struct Vec_Bit_t_ Vec_Bit_t
INCLUDES ///.
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.