180 int nSize = nCands * nCands * (nGatesMax + 1) * 5;
183 Bdc_Nod_t * pNode, * pNode0, * pNode1, * pNode2;
184 int Count0, Count1, * pPerm;
187 assert( nGatesMax < (1<<8) );
188 assert( nCands < (1<<12) );
189 assert( (1<<(nVars-1))*(1<<(nVars-1)) < (1<<12) );
191 printf(
"Storage size = %d (%d * %d * %d * %d).\n", nSize, nCands, nCands, nGatesMax + 1, 5 );
193 printf(
"SPFD = %d.\n", Bdc_CountOnes(Truth) * Bdc_CountOnes(~Truth) );
196 if ( Truth == 0 || Truth == ~0 )
198 printf(
"Function is a constant.\n" );
201 for ( i = 0; i < nVars; i++ )
202 if ( Truth == Truths[i] || Truth == ~Truths[i] )
204 printf(
"Function is an elementary variable.\n" );
209 vLevels = Vec_PtrAlloc( 100 );
210 vBegs = Vec_IntAlloc( 100 );
211 vWeight = Vec_IntAlloc( 100 );
215 for ( i = 0; i < nVars; i++ )
216 pNode[i].Truth = Truths[i];
217 for ( i = 0; i < nVars; i++ )
218 pNode[i].Weight = Bdc_CountSpfd( pNode[i].Truth, Truth );
219 Vec_PtrPush( vLevels, pNode );
220 Vec_IntPush( vBegs, nVars );
226 for ( c = i = 0; i < nVars; i++ )
227 for ( j = i+1; j < nVars; j++ )
229 pNode[c].Truth = pNode0[i].Truth & pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 0;
230 pNode[c].Truth = ~pNode0[i].Truth & pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 1;
231 pNode[c].Truth = pNode0[i].Truth & ~pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 2;
232 pNode[c].Truth = ~pNode0[i].Truth & ~pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 3;
233 pNode[c].Truth = pNode0[i].Truth ^ pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 4;
235 assert( c == 5 * nVars * (nVars - 1) / 2 );
236 Vec_PtrPush( vLevels, pNode );
237 Vec_IntPush( vBegs, c );
238 for ( i = 0; i < c; i++ )
240 pNode[i].Weight = Bdc_CountSpfd( pNode[i].Truth, Truth );
242 if ( Truth == pNode[i].Truth || Truth == ~pNode[i].Truth )
244 printf(
"Function can be implemented using 1 gate.\n" );
249printf(
"Selected %6d gates on level %2d. ", c, 1 );
250Abc_PrintTime( 1,
"Time", Abc_Clock() - clk );
255 for ( n = 2; n <= nGatesMax; n++ )
259 pNode1 = (
Bdc_Nod_t *)Vec_PtrEntry( vLevels, n-1 );
260 Count1 = Vec_IntEntry( vBegs, n-1 );
262 for ( k = 0; k < n-1; k++ )
264 pNode0 = (
Bdc_Nod_t *)Vec_PtrEntry( vLevels, k );
265 Count0 = Vec_IntEntry( vBegs, k );
266 for ( i = 0; i < Count0; i++ )
267 for ( j = 0; j < Count1; j++ )
269 pNode[c].Truth = pNode0[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 0;
270 pNode[c].Truth = ~pNode0[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 1;
271 pNode[c].Truth = pNode0[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 2;
272 pNode[c].Truth = ~pNode0[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 3;
273 pNode[c].Truth = pNode0[i].Truth ^ pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 4;
278 for ( i = 0; i < Count1; i++ )
279 for ( j = i+1; j < Count1; j++ )
281 pNode[c].Truth = pNode1[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 0;
282 pNode[c].Truth = ~pNode1[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 1;
283 pNode[c].Truth = pNode1[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 2;
284 pNode[c].Truth = ~pNode1[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 3;
285 pNode[c].Truth = pNode1[i].Truth ^ pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 4;
289 Vec_IntClear( vWeight );
290 for ( i = 0; i < c; i++ )
292 pNode[i].Weight = Bdc_CountSpfd( pNode[i].Truth, Truth );
293if ( pNode[i].Weight > 300 )
295 Vec_IntPush( vWeight, pNode[i].Weight );
297 if ( Truth == pNode[i].Truth || Truth == ~pNode[i].Truth )
299 printf(
"Function can be implemented using %d gates.\n", n );
305 assert( Vec_IntEntry(vWeight, pPerm[0]) <= Vec_IntEntry(vWeight, pPerm[c-1]) );
307 printf(
"Best SPFD = %d.\n", Vec_IntEntry(vWeight, pPerm[c-1]) );
313 for ( j = 0, i = c-1; i >= 0; i-- )
315 pNode2[j++] = pNode[pPerm[i]];
320 Vec_PtrPush( vLevels, pNode2 );
321 Vec_IntPush( vBegs, j );
323printf(
"Selected %6d gates (out of %6d) on level %2d. ", j, c, n );
324Abc_PrintTime( 1,
"Time", Abc_Clock() - clk );
326 for ( i = 0; i < 10; i++ )
334 Vec_PtrFree( vLevels );
335 Vec_IntFree( vBegs );
336 Vec_IntFree( vWeight );
587 int nFuncs = 250000000;
588 int nSize = 201326611;
591 int * pPlace, i, n, m, k, s, fCompl;
592 abctime clk = Abc_Clock(), clk2;
596 Bdc_Ent_t *
p, * q, * pBeg0, * pEnd0, * pBeg1, * pEnd1, * pThis0, * pThis1;
598 assert( nSize <= nFuncs );
600 printf(
"Allocating %.2f MB of internal memory.\n", 1.0*
sizeof(
Bdc_Ent_t)*nFuncs/(1<<20) );
605 for ( q =
p; q <
p+nFuncs; q++ )
608 printf(
"Added %d + %d + 0 = %d. Total = %8d.\n", 0, 0, 0, (
int)(q-
p) );
610 vTruths = Vec_WrdStart( nFuncs );
611 vWeights = Vec_IntStart( nFuncs );
612 Vec_WrdClear( vTruths );
613 Vec_IntClear( vWeights );
616 vStops = Vec_IntAlloc( 10 );
617 Vec_IntPush( vStops, 1 );
618 for ( i = 0; i < 6; i++ )
622 q->
Truth = Truths[i];
626 Vec_WrdPush( vTruths, Truths[i] );
627 Vec_IntPush( vWeights, 0 );
629 Vec_IntPush( vStops, 7 );
630 printf(
"Added %d + %d + 0 = %d. Total = %8d.\n", 0, 0, 0, (
int)(q-
p) );
633 for ( n = 0; n < Limit; n++ )
636 for ( k = 0; k < Limit; k++ )
637 for ( m = 0; m < Limit; m++ )
639 if ( k + m != n || k > m )
642 pBeg0 =
p + Vec_IntEntry( vStops, k );
643 pEnd0 =
p + Vec_IntEntry( vStops, k+1 );
645 pBeg1 =
p + Vec_IntEntry( vStops, m );
646 pEnd1 =
p + Vec_IntEntry( vStops, m+1 );
649 printf(
"Trying %7d x %7d. ", (
int)(pEnd0-pBeg0), (
int)(pEnd1-pBeg1) );
650 for ( pThis0 = pBeg0; pThis0 < pEnd0; pThis0++ )
651 for ( pThis1 = pBeg1; pThis1 < pEnd1; pThis1++ )
652 if ( k < m || pThis1 > pThis0 )
654 for ( s = 0; s < 5; s++ )
656 t0 = (s&1) ? ~pThis0->Truth : pThis0->Truth;
657 t1 = ((s>>1)&1) ? ~pThis1->
Truth : pThis1->
Truth;
658 t = ((s>>2)&1) ? t0 ^ t1 : t0 & t1;
665 if ( pPlace == NULL )
676 Vec_WrdPush( vTruths, t );
678 Vec_IntPush( vWeights, n+1 );
681 printf(
"Reached limit of %d functions.\n", nFuncs );
685 printf(
"Added %d + %d + 1 = %d. Total = %8d. ", k, m, n+1, (
int)(q-
p) );
686 Abc_PrintTime( 1,
"Time", Abc_Clock() - clk2 );
688 Vec_IntPush( vStops, q-
p );
690 Abc_PrintTime( 1,
"Time", Abc_Clock() - clk );
694 FILE * pFile = fopen(
"func6v6n_bin.txt",
"wb" );
695 fwrite( Vec_WrdArray(vTruths),
sizeof(
word), Vec_WrdSize(vTruths), pFile );
699 FILE * pFile = fopen(
"func6v6nW_bin.txt",
"wb" );
700 fwrite( Vec_IntArray(vWeights),
sizeof(
int), Vec_IntSize(vWeights), pFile );
706 Vec_IntFree( vStops );
709 *pvWeights = vWeights;
810 int i, Cost, CostBest = -1, NumBest = -1;
813 if ( (Func & F0) == 0 )
816 if ( CostBest < Cost )
823 if ( (Func & F1) == 0 )
826 if ( CostBest < Cost )
833 if ( (~Func & F0) == 0 )
836 if ( CostBest < Cost )
843 if ( (~Func & F1) == 0 )
846 if ( CostBest < Cost )
854 (*pCost) += Vec_IntEntry(vWeights, NumBest);
856 printf(
"Selected %8d with cost %2d and weight %d: ", NumBest, 0, Vec_IntEntry(vWeights, NumBest) );
857 Extra_PrintHex( stdout, (
unsigned *)&FuncBest, 6 ); printf(
"\n" );