ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
bmcMaj2.c
Go to the documentation of this file.
1
20
21#include "bmc.h"
22#include "misc/extra/extra.h"
23#include "misc/util/utilTruth.h"
24#include "sat/cnf/cnf.h"
25#include "sat/bsat/satStore.h"
26
28
32
33#define MAJ_NOBJS 32 // Const0 + Const1 + nVars + nNodes
34
35typedef struct Maj_Man_t_ Maj_Man_t;
36struct Maj_Man_t_
37{
38 int nVars; // inputs
39 int nNodes; // internal nodes
40 int nObjs; // total objects (2 consts, nVars inputs, nNodes internal nodes)
41 int nWords; // the truth table size in 64-bit words
42 int iVar; // the next available SAT variable
43 int fUseConst; // use constant fanins
44 int fUseLine; // use cascade topology
45 int fUseRand; // use random topology
46 int nRands; // number of random connections
47 int fVerbose; // verbose flag
48 Vec_Wrd_t * vInfo; // Const0 + Const1 + nVars + nNodes + Maj(nVars)
49 int VarMarks[MAJ_NOBJS][3][MAJ_NOBJS]; // variable marks
50 int VarVals[MAJ_NOBJS+2]; // values of the first 2 + nVars variables
51 Vec_Wec_t * vOutLits; // output vars
52 sat_solver * pSat; // SAT solver
53};
54
55static inline word * Maj_ManTruth( Maj_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); }
56
60
72static int Maj_ManValue( int iMint, int nVars )
73{
74 int k, Count = 0;
75 for ( k = 0; k < nVars; k++ )
76 Count += (iMint >> k) & 1;
77 return (int)(Count > nVars/2);
78}
80{
81 Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs + 1) );
82 int i, nMints = Abc_MaxInt( 64, 1 << p->nVars );
83 Abc_TtFill( Maj_ManTruth(p, 1), p->nWords );
84 for ( i = 0; i < p->nVars; i++ )
85 Abc_TtIthVar( Maj_ManTruth(p, i+2), i, p->nVars );
86 for ( i = 0; i < nMints; i++ )
87 if ( Maj_ManValue(i, p->nVars) )
88 Abc_TtSetBit( Maj_ManTruth(p, p->nObjs), i );
89 //Dau_DsdPrintFromTruth( Maj_ManTruth(p, p->nObjs), p->nVars );
90 return vInfo;
91}
92static void Maj_ManConnect( int VarCons[MAJ_NOBJS][3], int nVars, int nObjs, int nRands, int fVerbose )
93{
94 int i, v, r, x;
95 srand(clock());
96 for ( i = nObjs-2; i >= nVars + 2; i-- )
97 {
98 while ( 1 )
99 {
100 int Index = 1 + (rand() % (nObjs-1-i));
101 for ( v = 2; v >= 0; v-- )
102// for ( v = 0; v < 3; v++ )
103 if ( VarCons[i+Index][v] == 0 )
104 {
105 VarCons[i+Index][v] = i;
106 if ( fVerbose )
107 printf( "%d -> %d ", i, i+Index );
108 break;
109 }
110 if ( v >= 0 )
111 break;
112 }
113 }
114 for ( r = 0; r < nRands; r++ )
115 {
116 i = nVars+2 + (rand() % ((nObjs-1)-(nVars+2)));
117 for ( x = 0; x < 100; x++ )
118 {
119 int Index = 1 + (rand() % (nObjs-1-i));
120 for ( v = 2; v >= 0; v-- )
121// for ( v = 0; v < 3; v++ )
122 {
123 if ( VarCons[i+Index][v] == i )
124 {
125 v = -1;
126 break;
127 }
128 if ( VarCons[i+Index][v] == 0 )
129 {
130 VarCons[i+Index][v] = i;
131 if ( fVerbose )
132 printf( "+%d -> %d ", i, i+Index );
133 break;
134 }
135 }
136 if ( v >= 0 )
137 break;
138 }
139 if ( x == 100 )
140 r--;
141 }
142 if ( fVerbose )
143 printf( "\n" );
144}
145static void Maj_ManConnect2( int VarCons[MAJ_NOBJS][3], int nVars, int nObjs, int nRands )
146{
147 VarCons[8+2][2] = 7+2;
148 VarCons[10+2][2] = 9+2;
149 VarCons[11+2][2] = 7+2;
150 VarCons[11+2][1] = 8+2;
151 VarCons[12+2][2] = 9+2;
152 VarCons[12+2][1] = 10+2;
153 VarCons[13+2][2] = 11+2;
154 VarCons[13+2][1] = 12+2;
155}
156static int Maj_ManMarkup( Maj_Man_t * p )
157{
158 int VarCons[MAJ_NOBJS][3] = {{0}};
159 int i, k, j, m;
160 p->iVar = 1;
161 assert( p->nObjs <= MAJ_NOBJS );
162 // create connections
163 if ( p->fUseRand )
164 Maj_ManConnect( VarCons, p->nVars, p->nObjs, p->nRands, p->fVerbose );
165 // make exception for the first node
166 i = p->nVars + 2;
167 for ( k = 0; k < 3; k++ )
168 {
169 j = 4-k;
170 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
171 p->VarMarks[i][k][j] = p->iVar++;
172 }
173 // assign variables for other nodes
174 for ( i = p->nVars + 3; i < p->nObjs; i++ )
175 {
176 for ( k = 0; k < 3; k++ )
177 {
178 if ( p->fUseLine && k == 0 )
179 {
180 j = i-1;
181 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
182 p->VarMarks[i][k][j] = p->iVar++;
183 continue;
184 }
185 if ( p->fUseRand && VarCons[i][k] > 0 )
186 {
187 j = VarCons[i][k];
188 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
189 p->VarMarks[i][k][j] = p->iVar++;
190 continue;
191 }
192
193 for ( j = (p->fUseConst && k == 2) ? 0 : 2; j < (p->fUseRand ? p->nVars+2-k : i-k); j++ )
194 {
195 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
196 p->VarMarks[i][k][j] = p->iVar++;
197 }
198 }
199 }
200 printf( "The number of parameter variables = %d.\n", p->iVar );
201 if ( !p->fVerbose )
202 return p->iVar;
203 // printout
204 printf( " " );
205 for ( i = p->nVars + 2; i < p->nObjs; i++ )
206 printf( " Node %2d ", i );
207 printf( "\n" );
208 for ( m = 0; m < p->nObjs; m++ )
209 {
210 printf( "%2d : ", m );
211 for ( i = p->nVars + 2; i < p->nObjs; i++ )
212 {
213 for ( j = 0; j < p->nObjs; j++ )
214 {
215 if ( j != m )
216 continue;
217 for ( k = 0; k < 3; k++ )
218 if ( p->VarMarks[i][k][j] )
219 printf( "%3d ", p->VarMarks[i][k][j] );
220 else
221 printf( "%3c ", '.' );
222 printf( " " );
223 }
224 }
225 printf( "\n" );
226 }
227 return p->iVar;
228}
229static Maj_Man_t * Maj_ManAlloc( int nVars, int nNodes, int fUseConst, int fUseLine, int fUseRand, int nRands, int fVerbose )
230{
232 p->nVars = nVars;
233 p->nNodes = nNodes;
234 p->nObjs = 2 + nVars + nNodes;
235 p->fUseConst = fUseConst;
236 p->fUseLine = fUseLine;
237 p->fUseRand = fUseRand;
238 p->fVerbose = fVerbose;
239 p->nRands = nRands;
240 p->nWords = Abc_TtWordNum(nVars);
241 p->vOutLits = Vec_WecStart( p->nObjs );
242 p->iVar = Maj_ManMarkup( p );
243 p->VarVals[1] = 1;
244 p->vInfo = Maj_ManTruthTables( p );
245 p->pSat = sat_solver_new();
246 sat_solver_setnvars( p->pSat, p->iVar );
247 return p;
248}
249static void Maj_ManFree( Maj_Man_t * p )
250{
251 sat_solver_delete( p->pSat );
252 Vec_WrdFree( p->vInfo );
253 Vec_WecFree( p->vOutLits );
254 ABC_FREE( p );
255}
256
257
269static inline int Maj_ManFindFanin( Maj_Man_t * p, int i, int k )
270{
271 int j, Count = 0, iVar = -1;
272 for ( j = 0; j < p->nObjs; j++ )
273 if ( p->VarMarks[i][k][j] && sat_solver_var_value(p->pSat, p->VarMarks[i][k][j]) )
274 {
275 iVar = j;
276 Count++;
277 }
278 assert( Count == 1 );
279 return iVar;
280}
281static inline int Maj_ManEval( Maj_Man_t * p )
282{
283 int fUseMiddle = 1;
284 static int Flag = 0;
285 int i, k, iMint; word * pFanins[3];
286 for ( i = p->nVars + 2; i < p->nObjs; i++ )
287 {
288 for ( k = 0; k < 3; k++ )
289 pFanins[k] = Maj_ManTruth( p, Maj_ManFindFanin(p, i, k) );
290 Abc_TtMaj( Maj_ManTruth(p, i), pFanins[0], pFanins[1], pFanins[2], p->nWords );
291 }
292 if ( fUseMiddle )
293 {
294 iMint = -1;
295 for ( i = 0; i < (1 << p->nVars); i++ )
296 {
297 int nOnes = Abc_TtBitCount16(i);
298 if ( nOnes < p->nVars/2 || nOnes > p->nVars/2+1 )
299 continue;
300 if ( Abc_TtGetBit(Maj_ManTruth(p, p->nObjs), i) == Abc_TtGetBit(Maj_ManTruth(p, p->nObjs-1), i) )
301 continue;
302 iMint = i;
303 break;
304 }
305 }
306 else
307 {
308 if ( Flag && p->nVars >= 6 )
309 iMint = Abc_TtFindLastDiffBit( Maj_ManTruth(p, p->nObjs-1), Maj_ManTruth(p, p->nObjs), p->nVars );
310 else
311 iMint = Abc_TtFindFirstDiffBit( Maj_ManTruth(p, p->nObjs-1), Maj_ManTruth(p, p->nObjs), p->nVars );
312 }
313 //Flag ^= 1;
314 assert( iMint < (1 << p->nVars) );
315 return iMint;
316}
317
329static void Maj_ManPrintSolution( Maj_Man_t * p )
330{
331 int i, k, iVar;
332 printf( "Realization of %d-input majority using %d MAJ3 gates:\n", p->nVars, p->nNodes );
333// for ( i = p->nVars + 2; i < p->nObjs; i++ )
334 for ( i = p->nObjs - 1; i >= p->nVars + 2; i-- )
335 {
336 printf( "%02d = MAJ(", i-2 );
337 for ( k = 2; k >= 0; k-- )
338 {
339 iVar = Maj_ManFindFanin( p, i, k );
340 if ( iVar >= 2 && iVar < p->nVars + 2 )
341 printf( " %c", 'a'+iVar-2 );
342 else if ( iVar < 2 )
343 printf( " %d", iVar );
344 else
345 printf( " %02d", iVar-2 );
346 }
347 printf( " )\n" );
348 }
349}
350
351
363static int Maj_ManAddCnfStart( Maj_Man_t * p )
364{
365 int pLits[MAJ_NOBJS], pLits2[2], i, j, k, n, m;
366 // input constraints
367 for ( i = p->nVars + 2; i < p->nObjs; i++ )
368 {
369 for ( k = 0; k < 3; k++ )
370 {
371 int nLits = 0;
372 for ( j = 0; j < p->nObjs; j++ )
373 if ( p->VarMarks[i][k][j] )
374 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 0 );
375 assert( nLits > 0 );
376 // input uniqueness
377 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
378 return 0;
379 for ( n = 0; n < nLits; n++ )
380 for ( m = n+1; m < nLits; m++ )
381 {
382 pLits2[0] = Abc_LitNot(pLits[n]);
383 pLits2[1] = Abc_LitNot(pLits[m]);
384 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
385 return 0;
386 }
387 if ( k == 2 || p->VarMarks[i][k][2] == 0 || p->VarMarks[i][k+1][2] == 0 )
388 continue;
389 // symmetry breaking
390 for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
391 for ( n = j; n < p->nObjs; n++ ) if ( p->VarMarks[i][k+1][n] )
392 {
393 pLits2[0] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
394 pLits2[1] = Abc_Var2Lit( p->VarMarks[i][k+1][n], 1 );
395 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
396 return 0;
397 }
398 }
399 }
400 // outputs should be used
401 for ( i = 2; i < p->nObjs - 1; i++ )
402 {
403 Vec_Int_t * vArray = Vec_WecEntry(p->vOutLits, i);
404 assert( Vec_IntSize(vArray) > 0 );
405 if ( !sat_solver_addclause( p->pSat, Vec_IntArray(vArray), Vec_IntLimit(vArray) ) )
406 return 0;
407 }
408 return 1;
409}
410static int Maj_ManAddCnf( Maj_Man_t * p, int iMint )
411{
412 // save minterm values
413 int i, k, n, j, Value = Maj_ManValue(iMint, p->nVars);
414 for ( i = 0; i < p->nVars; i++ )
415 p->VarVals[i+2] = (iMint >> i) & 1;
416 sat_solver_setnvars( p->pSat, p->iVar + 4*p->nNodes );
417 //printf( "Adding clauses for minterm %d.\n", iMint );
418 for ( i = p->nVars + 2; i < p->nObjs; i++ )
419 {
420 // fanin connectivity
421 int iBaseSatVarI = p->iVar + 4*(i - p->nVars - 2);
422 for ( k = 0; k < 3; k++ )
423 {
424 for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
425 {
426 int iBaseSatVarJ = p->iVar + 4*(j - p->nVars - 2);
427 for ( n = 0; n < 2; n++ )
428 {
429 int pLits[3], nLits = 0;
430 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
431 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + k, n );
432 if ( j >= p->nVars + 2 )
433 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarJ + 3, !n );
434 else if ( p->VarVals[j] == n )
435 continue;
436 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
437 return 0;
438 }
439 }
440 }
441 // node functionality
442 for ( n = 0; n < 2; n++ )
443 {
444 if ( i == p->nObjs - 1 && n == Value )
445 continue;
446 for ( k = 0; k < 3; k++ )
447 {
448 int pLits[3], nLits = 0;
449 if ( k != 0 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 0, n );
450 if ( k != 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 1, n );
451 if ( k != 2 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 2, n );
452 if ( i != p->nObjs - 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 3, !n );
453 assert( nLits <= 3 );
454 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
455 return 0;
456 }
457 }
458 }
459 p->iVar += 4*p->nNodes;
460 return 1;
461}
462int Maj_ManExactSynthesis2( int nVars, int nNodes, int fUseConst, int fUseLine, int fUseRand, int nRands, int fVerbose )
463{
464 int i, iMint = 0;
465 abctime clkTotal = Abc_Clock();
466 Maj_Man_t * p = Maj_ManAlloc( nVars, nNodes, fUseConst, fUseLine, fUseRand, nRands, fVerbose );
467 int status = Maj_ManAddCnfStart( p );
468 assert( status );
469 if ( fVerbose )
470 printf( "Running exact synthesis for %d-input majority with %d MAJ3 gates...\n", p->nVars, p->nNodes );
471 for ( i = 0; iMint != -1; i++ )
472 {
473 abctime clk = Abc_Clock();
474 if ( !Maj_ManAddCnf( p, iMint ) )
475 {
476 printf( "The problem has no solution after %2d iterations. ", i+1 );
477 break;
478 }
479 status = sat_solver_solve( p->pSat, NULL, NULL, 0, 0, 0, 0 );
480 if ( fVerbose )
481 {
482 printf( "Iter %3d : ", i );
483 Extra_PrintBinary( stdout, (unsigned *)&iMint, p->nVars );
484 printf( " Var =%5d ", p->iVar );
485 printf( "Cla =%6d ", sat_solver_nclauses(p->pSat) );
486 printf( "Conf =%9d ", sat_solver_nconflicts(p->pSat) );
487 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
488 }
489 if ( status == l_False )
490 {
491 printf( "The problem has no solution after %2d iterations. ", i+1 );
492 break;
493 }
494 iMint = Maj_ManEval( p );
495 }
496 if ( iMint == -1 )
498 Maj_ManFree( p );
499 Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
500 return iMint == -1;
501}
502
504{
505// while ( !Maj_ManExactSynthesis2( 5, 4, 0, 0, 1, 1, 0 ) );
506// while ( !Maj_ManExactSynthesis2( 7, 7, 0, 0, 1, 2, 0 ) );
507 while ( !Maj_ManExactSynthesis2( 9, 10, 0, 0, 1, 3, 0 ) );
508 return 1;
509}
510
511
512
513
514
515
516typedef struct Exa_Man_t_ Exa_Man_t;
517struct Exa_Man_t_
518{
519 Bmc_EsPar_t * pPars; // parameters
520 int nVars; // inputs
521 int nNodes; // internal nodes
522 int nObjs; // total objects (nVars inputs + nNodes internal nodes)
523 int nWords; // the truth table size in 64-bit words
524 int iVar; // the next available SAT variable
525 word * pTruth; // truth table
526 Vec_Wrd_t * vInfo; // nVars + nNodes + 1
527 int VarMarks[MAJ_NOBJS][2][MAJ_NOBJS]; // variable marks
528 int VarVals[MAJ_NOBJS]; // values of the first nVars variables
529 Vec_Wec_t * vOutLits; // output vars
530 sat_solver * pSat; // SAT solver
531};
532
533static inline word * Exa_ManTruth( Exa_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); }
534
535
548{
549 Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs+1) ); int i;
550 for ( i = 0; i < p->nVars; i++ )
551 Abc_TtIthVar( Exa_ManTruth(p, i), i, p->nVars );
552 //Dau_DsdPrintFromTruth( Exa_ManTruth(p, p->nObjs), p->nVars );
553 return vInfo;
554}
555static int Exa_ManMarkup( Exa_Man_t * p )
556{
557 int i, k, j;
558 assert( p->nObjs <= MAJ_NOBJS );
559 // assign functionality
560 p->iVar = 1 + p->nNodes * 3;
561 // assign connectivity variables
562 for ( i = p->nVars; i < p->nObjs; i++ )
563 {
564 for ( k = 0; k < 2; k++ )
565 {
566 if ( p->pPars->fFewerVars && i == p->nObjs - 1 && k == 0 )
567 {
568 j = p->nObjs - 2;
569 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
570 p->VarMarks[i][k][j] = p->iVar++;
571 continue;
572 }
573 for ( j = p->pPars->fFewerVars ? 1 - k : 0; j < i - k; j++ )
574 {
575 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
576 p->VarMarks[i][k][j] = p->iVar++;
577 }
578 }
579 }
580 printf( "The number of parameter variables = %d.\n", p->iVar );
581 return p->iVar;
582 // printout
583 for ( i = p->nVars; i < p->nObjs; i++ )
584 {
585 printf( "Node %d\n", i );
586 for ( j = 0; j < p->nObjs; j++ )
587 {
588 for ( k = 0; k < 2; k++ )
589 printf( "%3d ", p->VarMarks[i][k][j] );
590 printf( "\n" );
591 }
592 }
593 return p->iVar;
594}
595static Exa_Man_t * Exa_ManAlloc( Bmc_EsPar_t * pPars, word * pTruth )
596{
598 p->pPars = pPars;
599 p->nVars = pPars->nVars;
600 p->nNodes = pPars->nNodes;
601 p->nObjs = pPars->nVars + pPars->nNodes;
602 p->nWords = Abc_TtWordNum(pPars->nVars);
603 p->pTruth = pTruth;
604 p->vOutLits = Vec_WecStart( p->nObjs );
605 p->iVar = Exa_ManMarkup( p );
606 p->vInfo = Exa_ManTruthTables( p );
607 p->pSat = sat_solver_new();
608 sat_solver_setnvars( p->pSat, p->iVar );
609 return p;
610}
611static void Exa_ManFree( Exa_Man_t * p )
612{
613 sat_solver_delete( p->pSat );
614 Vec_WrdFree( p->vInfo );
615 Vec_WecFree( p->vOutLits );
616 ABC_FREE( p );
617}
618
619
631static inline int Exa_ManFindFanin( Exa_Man_t * p, int i, int k )
632{
633 int j, Count = 0, iVar = -1;
634 for ( j = 0; j < p->nObjs; j++ )
635 if ( p->VarMarks[i][k][j] && sat_solver_var_value(p->pSat, p->VarMarks[i][k][j]) )
636 {
637 iVar = j;
638 Count++;
639 }
640 assert( Count == 1 );
641 return iVar;
642}
643static inline int Exa_ManEval( Exa_Man_t * p )
644{
645 static int Flag = 0;
646 int i, k, iMint; word * pFanins[2];
647 for ( i = p->nVars; i < p->nObjs; i++ )
648 {
649 int iVarStart = 1 + 3*(i - p->nVars);
650 for ( k = 0; k < 2; k++ )
651 pFanins[k] = Exa_ManTruth( p, Exa_ManFindFanin(p, i, k) );
652 Abc_TtConst0( Exa_ManTruth(p, i), p->nWords );
653 for ( k = 1; k < 4; k++ )
654 {
655 if ( !sat_solver_var_value(p->pSat, iVarStart+k-1) )
656 continue;
657 Abc_TtAndCompl( Exa_ManTruth(p, p->nObjs), pFanins[0], !(k&1), pFanins[1], !(k>>1), p->nWords );
658 Abc_TtOr( Exa_ManTruth(p, i), Exa_ManTruth(p, i), Exa_ManTruth(p, p->nObjs), p->nWords );
659 }
660 }
661 if ( Flag && p->nVars >= 6 )
662 iMint = Abc_TtFindLastDiffBit( Exa_ManTruth(p, p->nObjs-1), p->pTruth, p->nVars );
663 else
664 iMint = Abc_TtFindFirstDiffBit( Exa_ManTruth(p, p->nObjs-1), p->pTruth, p->nVars );
665 //Flag ^= 1;
666 assert( iMint < (1 << p->nVars) );
667 return iMint;
668}
669
681static void Exa_ManPrintSolution( Exa_Man_t * p, int fCompl )
682{
683 int i, k, iVar;
684 printf( "Realization of given %d-input function using %d two-input gates:\n", p->nVars, p->nNodes );
685// for ( i = p->nVars + 2; i < p->nObjs; i++ )
686 for ( i = p->nObjs - 1; i >= p->nVars; i-- )
687 {
688 int iVarStart = 1 + 3*(i - p->nVars);
689 int Val1 = sat_solver_var_value(p->pSat, iVarStart);
690 int Val2 = sat_solver_var_value(p->pSat, iVarStart+1);
691 int Val3 = sat_solver_var_value(p->pSat, iVarStart+2);
692 if ( i == p->nObjs - 1 && fCompl )
693 printf( "%02d = 4\'b%d%d%d1(", i, !Val3, !Val2, !Val1 );
694 else
695 printf( "%02d = 4\'b%d%d%d0(", i, Val3, Val2, Val1 );
696 for ( k = 1; k >= 0; k-- )
697 {
698 iVar = Exa_ManFindFanin( p, i, k );
699 if ( iVar >= 0 && iVar < p->nVars )
700 printf( " %c", 'a'+iVar );
701 else
702 printf( " %02d", iVar );
703 }
704 printf( " )\n" );
705 }
706}
707
708
720static int Exa_ManAddCnfStart( Exa_Man_t * p, int fOnlyAnd )
721{
722 int pLits[MAJ_NOBJS], pLits2[2], i, j, k, n, m;
723 // input constraints
724 for ( i = p->nVars; i < p->nObjs; i++ )
725 {
726 int iVarStart = 1 + 3*(i - p->nVars);
727 for ( k = 0; k < 2; k++ )
728 {
729 int nLits = 0;
730 for ( j = 0; j < p->nObjs; j++ )
731 if ( p->VarMarks[i][k][j] )
732 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 0 );
733 assert( nLits > 0 );
734 // input uniqueness
735 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
736 return 0;
737 for ( n = 0; n < nLits; n++ )
738 for ( m = n+1; m < nLits; m++ )
739 {
740 pLits2[0] = Abc_LitNot(pLits[n]);
741 pLits2[1] = Abc_LitNot(pLits[m]);
742 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
743 return 0;
744 }
745 if ( k == 1 )
746 break;
747 // symmetry breaking
748 for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
749 for ( n = j; n < p->nObjs; n++ ) if ( p->VarMarks[i][k+1][n] )
750 {
751 pLits2[0] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
752 pLits2[1] = Abc_Var2Lit( p->VarMarks[i][k+1][n], 1 );
753 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
754 return 0;
755 }
756 }
757#ifdef USE_NODE_ORDER
758 // node ordering
759 for ( j = p->nVars; j < i; j++ )
760 for ( n = 0; n < p->nObjs; n++ ) if ( p->VarMarks[i][0][n] )
761 for ( m = n+1; m < p->nObjs; m++ ) if ( p->VarMarks[j][0][m] )
762 {
763 pLits2[0] = Abc_Var2Lit( p->VarMarks[i][0][n], 1 );
764 pLits2[1] = Abc_Var2Lit( p->VarMarks[j][0][m], 1 );
765 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
766 return 0;
767 }
768#endif
769 // two input functions
770 for ( k = 0; k < 3; k++ )
771 {
772 pLits[0] = Abc_Var2Lit( iVarStart, k==1 );
773 pLits[1] = Abc_Var2Lit( iVarStart+1, k==2 );
774 pLits[2] = Abc_Var2Lit( iVarStart+2, k!=0 );
775 if ( !sat_solver_addclause( p->pSat, pLits, pLits+3 ) )
776 return 0;
777 }
778 if ( fOnlyAnd )
779 {
780 pLits[0] = Abc_Var2Lit( iVarStart, 1 );
781 pLits[1] = Abc_Var2Lit( iVarStart+1, 1 );
782 pLits[2] = Abc_Var2Lit( iVarStart+2, 0 );
783 if ( !sat_solver_addclause( p->pSat, pLits, pLits+3 ) )
784 return 0;
785 }
786 }
787 // outputs should be used
788 for ( i = 0; i < p->nObjs - 1; i++ )
789 {
790 Vec_Int_t * vArray = Vec_WecEntry(p->vOutLits, i);
791 assert( Vec_IntSize(vArray) > 0 );
792 if ( !sat_solver_addclause( p->pSat, Vec_IntArray(vArray), Vec_IntLimit(vArray) ) )
793 return 0;
794 }
795 return 1;
796}
797static int Exa_ManAddCnf( Exa_Man_t * p, int iMint )
798{
799 // save minterm values
800 int i, k, n, j, Value = Abc_TtGetBit(p->pTruth, iMint);
801 for ( i = 0; i < p->nVars; i++ )
802 p->VarVals[i] = (iMint >> i) & 1;
803 sat_solver_setnvars( p->pSat, p->iVar + 3*p->nNodes );
804 //printf( "Adding clauses for minterm %d with value %d.\n", iMint, Value );
805 for ( i = p->nVars; i < p->nObjs; i++ )
806 {
807 // fanin connectivity
808 int iVarStart = 1 + 3*(i - p->nVars);
809 int iBaseSatVarI = p->iVar + 3*(i - p->nVars);
810 for ( k = 0; k < 2; k++ )
811 {
812 for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
813 {
814 int iBaseSatVarJ = p->iVar + 3*(j - p->nVars);
815 for ( n = 0; n < 2; n++ )
816 {
817 int pLits[3], nLits = 0;
818 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
819 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + k, n );
820 if ( j >= p->nVars )
821 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarJ + 2, !n );
822 else if ( p->VarVals[j] == n )
823 continue;
824 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
825 return 0;
826 }
827 }
828 }
829 // node functionality
830 for ( n = 0; n < 2; n++ )
831 {
832 if ( i == p->nObjs - 1 && n == Value )
833 continue;
834 for ( k = 0; k < 4; k++ )
835 {
836 int pLits[4], nLits = 0;
837 if ( k == 0 && n == 1 )
838 continue;
839 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 0, (k&1) );
840 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 1, (k>>1) );
841 if ( i != p->nObjs - 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 2, !n );
842 if ( k > 0 ) pLits[nLits++] = Abc_Var2Lit( iVarStart + k-1, n );
843 assert( nLits <= 4 );
844 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
845 return 0;
846 }
847 }
848 }
849 p->iVar += 3*p->nNodes;
850 return 1;
851}
853{
854 int i, status, iMint = 1;
855 abctime clkTotal = Abc_Clock();
856 Exa_Man_t * p; int fCompl = 0;
857 word pTruth[16]; Abc_TtReadHex( pTruth, pPars->pTtStr );
858 assert( pPars->nVars <= 10 );
859 p = Exa_ManAlloc( pPars, pTruth );
860 if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, p->nWords ); }
861 status = Exa_ManAddCnfStart( p, pPars->fOnlyAnd );
862 assert( status );
863 printf( "Running exact synthesis for %d-input function with %d two-input gates...\n", p->nVars, p->nNodes );
864 for ( i = 0; iMint != -1; i++ )
865 {
866 abctime clk = Abc_Clock();
867 if ( !Exa_ManAddCnf( p, iMint ) )
868 break;
869 status = sat_solver_solve( p->pSat, NULL, NULL, 0, 0, 0, 0 );
870 if ( pPars->fVerbose )
871 {
872 printf( "Iter %3d : ", i );
873 Extra_PrintBinary( stdout, (unsigned *)&iMint, p->nVars );
874 printf( " Var =%5d ", p->iVar );
875 printf( "Cla =%6d ", sat_solver_nclauses(p->pSat) );
876 printf( "Conf =%9d ", sat_solver_nconflicts(p->pSat) );
877 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
878 }
879 if ( status == l_False )
880 {
881 printf( "The problem has no solution.\n" );
882 break;
883 }
884 iMint = Exa_ManEval( p );
885 }
886 if ( iMint == -1 )
887 Exa_ManPrintSolution( p, fCompl );
888 Exa_ManFree( p );
889 Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
890}
891
892
893
894
895
896
897typedef struct Exa3_Man_t_ Exa3_Man_t;
898struct Exa3_Man_t_
899{
900 Bmc_EsPar_t * pPars; // parameters
901 int nVars; // inputs
902 int nNodes; // internal nodes
903 int nLutSize; // lut size
904 int LutMask; // lut mask
905 int nObjs; // total objects (nVars inputs + nNodes internal nodes)
906 int nWords; // the truth table size in 64-bit words
907 int iVar; // the next available SAT variable
908 word * pTruth; // truth table
909 Vec_Wrd_t * vInfo; // nVars + nNodes + 1
910 int VarMarks[MAJ_NOBJS][6][MAJ_NOBJS]; // variable marks
911 int VarVals[MAJ_NOBJS]; // values of the first nVars variables
912 Vec_Wec_t * vOutLits; // output vars
913 sat_solver * pSat; // SAT solver
914};
915
916static inline word * Exa3_ManTruth( Exa3_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); }
917
918
930static Vec_Wrd_t * Exa3_ManTruthTables( Exa3_Man_t * p )
931{
932 Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs+1) ); int i;
933 for ( i = 0; i < p->nVars; i++ )
934 Abc_TtIthVar( Exa3_ManTruth(p, i), i, p->nVars );
935 //Dau_DsdPrintFromTruth( Exa3_ManTruth(p, p->nObjs), p->nVars );
936 return vInfo;
937}
938static int Exa3_ManMarkup( Exa3_Man_t * p )
939{
940 int i, k, j;
941 assert( p->nObjs <= MAJ_NOBJS );
942 // assign functionality variables
943 p->iVar = 1 + p->LutMask * p->nNodes;
944 // assign connectivity variables
945 for ( i = p->nVars; i < p->nObjs; i++ )
946 {
947 if ( p->pPars->fLutCascade )
948 {
949 if ( i > p->nVars )
950 {
951 Vec_WecPush( p->vOutLits, i-1, Abc_Var2Lit(p->iVar, 0) );
952 p->VarMarks[i][0][i-1] = p->iVar++;
953 }
954 for ( k = (int)(i > p->nVars); k < p->nLutSize; k++ )
955 {
956 for ( j = 0; j < p->nVars - k + (int)(i > p->nVars); j++ )
957 {
958 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
959 p->VarMarks[i][k][j] = p->iVar++;
960 }
961 }
962 continue;
963 }
964 for ( k = 0; k < p->nLutSize; k++ )
965 {
966 if ( p->pPars->fFewerVars && i == p->nObjs - 1 && k == 0 )
967 {
968 j = p->nObjs - 2;
969 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
970 p->VarMarks[i][k][j] = p->iVar++;
971 continue;
972 }
973 for ( j = p->pPars->fFewerVars ? p->nLutSize - 1 - k : 0; j < i - k; j++ )
974 {
975 Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
976 p->VarMarks[i][k][j] = p->iVar++;
977 }
978 }
979 }
980 printf( "The number of parameter variables = %d.\n", p->iVar );
981 return p->iVar;
982 // printout
983// for ( i = p->nVars; i < p->nObjs; i++ )
984 for ( i = p->nObjs - 1; i >= p->nVars; i-- )
985 {
986 printf( " Node %2d\n", i );
987 for ( j = 0; j < p->nObjs; j++ )
988 {
989 printf( "Fanin %2d : ", j );
990 for ( k = 0; k < p->nLutSize; k++ )
991 printf( "%3d ", p->VarMarks[i][k][j] );
992 printf( "\n" );
993 }
994 }
995 return p->iVar;
996}
997static int Exa3_ManInitPolarityFindVar( Exa3_Man_t * p, int i, int k, int * pIndex )
998{
999 int iVar;
1000 do {
1001 iVar = p->VarMarks[i][k][*pIndex];
1002 *pIndex = (*pIndex + 1) % p->nVars;
1003 } while ( iVar <= 0 );
1004 //intf( "Setting var %d.\n", iVar );
1005 return iVar;
1006}
1007static void Exa3_ManInitPolarity( Exa3_Man_t * p )
1008{
1009 int i, k, iVar, nInputs = 0;
1010 for ( i = p->nVars; i < p->nObjs; i++ )
1011 {
1012 // create AND-gate
1013 int iVarStart = 1 + p->LutMask*(i - p->nVars);
1014 iVar = iVarStart + p->LutMask-1;
1015 p->pSat->polarity[iVar] = 1;
1016 //printf( "Setting var %d.\n", iVar );
1017 }
1018 for ( i = p->nVars; i < p->nObjs; i++ )
1019 {
1020 // connect first fanin to previous
1021 if ( i == p->nVars )
1022 {
1023 for ( k = p->nLutSize - 1; k >= 0; k-- )
1024 {
1025 iVar = Exa3_ManInitPolarityFindVar( p, i, k, &nInputs );
1026 p->pSat->polarity[iVar] = 1;
1027 }
1028 }
1029 else
1030 {
1031 for ( k = p->nLutSize - 1; k > 0; k-- )
1032 {
1033 iVar = Exa3_ManInitPolarityFindVar( p, i, k, &nInputs );
1034 p->pSat->polarity[iVar] = 1;
1035 }
1036 iVar = p->VarMarks[i][0][i-1];
1037 if ( iVar <= 0 ) printf( "Variable mapping error.\n" ), fflush(stdout);
1038 assert( iVar > 0 );
1039 p->pSat->polarity[iVar] = 1;
1040 //intf( "Setting var %d.\n", iVar );
1041 }
1042 //intf( "\n" );
1043 }
1044}
1045static Exa3_Man_t * Exa3_ManAlloc( Bmc_EsPar_t * pPars, word * pTruth )
1046{
1048 p->pPars = pPars;
1049 p->nVars = pPars->nVars;
1050 p->nNodes = pPars->nNodes;
1051 p->nLutSize = pPars->nLutSize;
1052 p->LutMask = (1 << pPars->nLutSize) - 1;
1053 p->nObjs = pPars->nVars + pPars->nNodes;
1054 p->nWords = Abc_TtWordNum(pPars->nVars);
1055 p->pTruth = pTruth;
1056 p->vOutLits = Vec_WecStart( p->nObjs );
1057 p->iVar = Exa3_ManMarkup( p );
1058 p->vInfo = Exa3_ManTruthTables( p );
1059 p->pSat = sat_solver_new();
1060 sat_solver_setnvars( p->pSat, p->iVar );
1061 //Exa3_ManInitPolarity( p );
1062 return p;
1063}
1064static void Exa3_ManFree( Exa3_Man_t * p )
1065{
1066 sat_solver_delete( p->pSat );
1067 Vec_WrdFree( p->vInfo );
1068 Vec_WecFree( p->vOutLits );
1069 ABC_FREE( p );
1070}
1071
1072
1084static inline int Exa3_ManFindFanin( Exa3_Man_t * p, int i, int k )
1085{
1086 int j, Count = 0, iVar = -1;
1087 for ( j = 0; j < p->nObjs; j++ )
1088 if ( p->VarMarks[i][k][j] && sat_solver_var_value(p->pSat, p->VarMarks[i][k][j]) )
1089 {
1090 iVar = j;
1091 Count++;
1092 }
1093 assert( Count == 1 );
1094 return iVar;
1095}
1096static inline int Exa3_ManEval( Exa3_Man_t * p )
1097{
1098 static int Flag = 0;
1099 int i, k, j, iMint; word * pFanins[6];
1100 for ( i = p->nVars; i < p->nObjs; i++ )
1101 {
1102 int iVarStart = 1 + p->LutMask*(i - p->nVars);
1103 for ( k = 0; k < p->nLutSize; k++ )
1104 pFanins[k] = Exa3_ManTruth( p, Exa3_ManFindFanin(p, i, k) );
1105 Abc_TtConst0( Exa3_ManTruth(p, i), p->nWords );
1106 for ( k = 1; k <= p->LutMask; k++ )
1107 {
1108 if ( !sat_solver_var_value(p->pSat, iVarStart+k-1) )
1109 continue;
1110// Abc_TtAndCompl( Exa3_ManTruth(p, p->nObjs), pFanins[0], !(k&1), pFanins[1], !(k>>1), p->nWords );
1111 Abc_TtConst1( Exa3_ManTruth(p, p->nObjs), p->nWords );
1112 for ( j = 0; j < p->nLutSize; j++ )
1113 Abc_TtAndCompl( Exa3_ManTruth(p, p->nObjs), Exa3_ManTruth(p, p->nObjs), 0, pFanins[j], !((k >> j) & 1), p->nWords );
1114 Abc_TtOr( Exa3_ManTruth(p, i), Exa3_ManTruth(p, i), Exa3_ManTruth(p, p->nObjs), p->nWords );
1115 }
1116 }
1117 if ( Flag && p->nVars >= 6 )
1118 iMint = Abc_TtFindLastDiffBit( Exa3_ManTruth(p, p->nObjs-1), p->pTruth, p->nVars );
1119 else
1120 iMint = Abc_TtFindFirstDiffBit( Exa3_ManTruth(p, p->nObjs-1), p->pTruth, p->nVars );
1121 //Flag ^= 1;
1122 assert( iMint < (1 << p->nVars) );
1123 return iMint;
1124}
1125
1137static void Exa3_ManPrintSolution( Exa3_Man_t * p, int fCompl )
1138{
1139 int i, k, iVar;
1140 printf( "Realization of given %d-input function using %d %d-input LUTs:\n", p->nVars, p->nNodes, p->nLutSize );
1141 for ( i = p->nObjs - 1; i >= p->nVars; i-- )
1142 {
1143 int Val, iVarStart = 1 + p->LutMask*(i - p->nVars);
1144
1145// int Val1 = sat_solver_var_value(p->pSat, iVarStart);
1146// int Val2 = sat_solver_var_value(p->pSat, iVarStart+1);
1147// int Val3 = sat_solver_var_value(p->pSat, iVarStart+2);
1148// if ( i == p->nObjs - 1 && fCompl )
1149// printf( "%02d = 4\'b%d%d%d1(", i, !Val3, !Val2, !Val1 );
1150// else
1151// printf( "%02d = 4\'b%d%d%d0(", i, Val3, Val2, Val1 );
1152
1153 printf( "%02d = %d\'b", i, 1 << p->nLutSize );
1154 for ( k = p->LutMask - 1; k >= 0; k-- )
1155 {
1156 Val = sat_solver_var_value(p->pSat, iVarStart+k);
1157 if ( i == p->nObjs - 1 && fCompl )
1158 printf( "%d", !Val );
1159 else
1160 printf( "%d", Val );
1161 }
1162 if ( i == p->nObjs - 1 && fCompl )
1163 printf( "1(" );
1164 else
1165 printf( "0(" );
1166
1167 for ( k = p->nLutSize - 1; k >= 0; k-- )
1168 {
1169 iVar = Exa3_ManFindFanin( p, i, k );
1170 if ( iVar >= 0 && iVar < p->nVars )
1171 printf( " %c", 'a'+iVar );
1172 else
1173 printf( " %02d", iVar );
1174 }
1175 printf( " )\n" );
1176 }
1177}
1178
1190static void Exa3_ManDumpBlif( Exa3_Man_t * p, int fCompl )
1191{
1192 int i, k, b, iVar;
1193 char pFileName[1000];
1194 sprintf( pFileName, "%s.blif", p->pPars->pTtStr );
1195 FILE * pFile = fopen( pFileName, "wb" );
1196 if ( pFile == NULL ) return;
1197 fprintf( pFile, "# Realization of given %d-input function using %d %d-input LUTs synthesized by ABC on %s\n", p->nVars, p->nNodes, p->nLutSize, Extra_TimeStamp() );
1198 fprintf( pFile, ".model %s\n", p->pPars->pTtStr );
1199 fprintf( pFile, ".inputs" );
1200 for ( k = 0; k < p->nVars; k++ )
1201 fprintf( pFile, " %c", 'a'+k );
1202 fprintf( pFile, "\n.outputs F\n" );
1203 for ( i = p->nObjs - 1; i >= p->nVars; i-- )
1204 {
1205 fprintf( pFile, ".names" );
1206 for ( k = 0; k < p->nLutSize; k++ )
1207 {
1208 iVar = Exa3_ManFindFanin( p, i, k );
1209 if ( iVar >= 0 && iVar < p->nVars )
1210 fprintf( pFile, " %c", 'a'+iVar );
1211 else
1212 fprintf( pFile, " %02d", iVar );
1213 }
1214 if ( i == p->nObjs - 1 )
1215 fprintf( pFile, " F\n" );
1216 else
1217 fprintf( pFile, " %02d\n", i );
1218 int iVarStart = 1 + p->LutMask*(i - p->nVars);
1219 for ( k = 0; k < p->LutMask; k++ )
1220 {
1221 int Val = sat_solver_var_value(p->pSat, iVarStart+k);
1222 if ( Val == 0 )
1223 continue;
1224 for ( b = 0; b < p->nLutSize; b++ )
1225 fprintf( pFile, "%d", ((k+1) >> b) & 1 );
1226 fprintf( pFile, " %d\n", i != p->nObjs - 1 || !fCompl );
1227 }
1228 }
1229 fprintf( pFile, ".end\n\n" );
1230 fclose( pFile );
1231 printf( "Finished dumping the resulting LUT network into file \"%s\".\n", pFileName );
1232}
1233
1234
1246static int Exa3_ManAddCnfStart( Exa3_Man_t * p, int fOnlyAnd )
1247{
1248 int pLits[MAJ_NOBJS], pLits2[2], i, j, k, n, m;
1249 // input constraints
1250 for ( i = p->nVars; i < p->nObjs; i++ )
1251 {
1252 int iVarStart = 1 + p->LutMask*(i - p->nVars);
1253 for ( k = 0; k < p->nLutSize; k++ )
1254 {
1255 int nLits = 0;
1256 for ( j = 0; j < p->nObjs; j++ )
1257 if ( p->VarMarks[i][k][j] )
1258 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 0 );
1259 assert( nLits > 0 );
1260 // input uniqueness
1261 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
1262 return 0;
1263 for ( n = 0; n < nLits; n++ )
1264 for ( m = n+1; m < nLits; m++ )
1265 {
1266 pLits2[0] = Abc_LitNot(pLits[n]);
1267 pLits2[1] = Abc_LitNot(pLits[m]);
1268 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
1269 return 0;
1270 }
1271 if ( k == p->nLutSize - 1 )
1272 break;
1273 // symmetry breaking
1274 for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
1275 for ( n = j; n < p->nObjs; n++ ) if ( p->VarMarks[i][k+1][n] )
1276 {
1277 pLits2[0] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
1278 pLits2[1] = Abc_Var2Lit( p->VarMarks[i][k+1][n], 1 );
1279 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
1280 return 0;
1281 }
1282 }
1283 //printf( "Node %d:\n", i );
1284 //sat_solver_flip_print_clause( p->pSat );
1285#ifdef USE_NODE_ORDER
1286 // node ordering
1287 for ( j = p->nVars; j < i; j++ )
1288 for ( n = 0; n < p->nObjs; n++ ) if ( p->VarMarks[i][0][n] )
1289 for ( m = n+1; m < p->nObjs; m++ ) if ( p->VarMarks[j][0][m] )
1290 {
1291 pLits2[0] = Abc_Var2Lit( p->VarMarks[i][0][n], 1 );
1292 pLits2[1] = Abc_Var2Lit( p->VarMarks[j][0][m], 1 );
1293 if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
1294 return 0;
1295 }
1296#endif
1297 if ( p->nLutSize != 2 )
1298 continue;
1299 // two-input functions
1300 for ( k = 0; k < 3; k++ )
1301 {
1302 pLits[0] = Abc_Var2Lit( iVarStart, k==1 );
1303 pLits[1] = Abc_Var2Lit( iVarStart+1, k==2 );
1304 pLits[2] = Abc_Var2Lit( iVarStart+2, k!=0 );
1305 if ( !sat_solver_addclause( p->pSat, pLits, pLits+3 ) )
1306 return 0;
1307 }
1308 if ( fOnlyAnd )
1309 {
1310 pLits[0] = Abc_Var2Lit( iVarStart, 1 );
1311 pLits[1] = Abc_Var2Lit( iVarStart+1, 1 );
1312 pLits[2] = Abc_Var2Lit( iVarStart+2, 0 );
1313 if ( !sat_solver_addclause( p->pSat, pLits, pLits+3 ) )
1314 return 0;
1315 }
1316 }
1317 // outputs should be used
1318 for ( i = 0; i < p->nObjs - 1; i++ )
1319 {
1320 Vec_Int_t * vArray = Vec_WecEntry(p->vOutLits, i);
1321 assert( Vec_IntSize(vArray) > 0 );
1322 if ( !sat_solver_addclause( p->pSat, Vec_IntArray(vArray), Vec_IntLimit(vArray) ) )
1323 return 0;
1324 }
1325 return 1;
1326}
1327static int Exa3_ManAddCnf( Exa3_Man_t * p, int iMint )
1328{
1329 // save minterm values
1330 int i, k, n, j, Value = Abc_TtGetBit(p->pTruth, iMint);
1331 for ( i = 0; i < p->nVars; i++ )
1332 p->VarVals[i] = (iMint >> i) & 1;
1333 sat_solver_setnvars( p->pSat, p->iVar + (p->nLutSize+1)*p->nNodes );
1334 //printf( "Adding clauses for minterm %d with value %d.\n", iMint, Value );
1335 for ( i = p->nVars; i < p->nObjs; i++ )
1336 {
1337 // fanin connectivity
1338 int iVarStart = 1 + p->LutMask*(i - p->nVars);
1339 int iBaseSatVarI = p->iVar + (p->nLutSize+1)*(i - p->nVars);
1340 for ( k = 0; k < p->nLutSize; k++ )
1341 {
1342 for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
1343 {
1344 int iBaseSatVarJ = p->iVar + (p->nLutSize+1)*(j - p->nVars);
1345 for ( n = 0; n < 2; n++ )
1346 {
1347 int pLits[3], nLits = 0;
1348 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
1349 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + k, n );
1350 if ( j >= p->nVars )
1351 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarJ + p->nLutSize, !n );
1352 else if ( p->VarVals[j] == n )
1353 continue;
1354 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
1355 return 0;
1356 }
1357 }
1358 }
1359 // node functionality
1360 for ( n = 0; n < 2; n++ )
1361 {
1362 if ( i == p->nObjs - 1 && n == Value )
1363 continue;
1364 for ( k = 0; k <= p->LutMask; k++ )
1365 {
1366 int pLits[8], nLits = 0;
1367 if ( k == 0 && n == 1 )
1368 continue;
1369 //pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 0, (k&1) );
1370 //pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 1, (k>>1) );
1371 //if ( i != p->nObjs - 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 2, !n );
1372 for ( j = 0; j < p->nLutSize; j++ )
1373 pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + j, (k >> j) & 1 );
1374 if ( i != p->nObjs - 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + j, !n );
1375 if ( k > 0 ) pLits[nLits++] = Abc_Var2Lit( iVarStart + k-1, n );
1376 assert( nLits <= p->nLutSize+2 );
1377 if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
1378 return 0;
1379 }
1380 }
1381 }
1382 p->iVar += (p->nLutSize+1)*p->nNodes;
1383 return 1;
1384}
1386{
1387 int i, status, iMint = 1;
1388 abctime clkTotal = Abc_Clock();
1389 Exa3_Man_t * p; int fCompl = 0;
1390 word pTruth[16];
1391 if ( pPars->pSymStr ) {
1392 word * pFun = Abc_TtSymFunGenerate( pPars->pSymStr, pPars->nVars );
1393 pPars->pTtStr = ABC_CALLOC( char, pPars->nVars > 2 ? (1 << (pPars->nVars-2)) + 1 : 2 );
1394 Extra_PrintHexadecimalString( pPars->pTtStr, (unsigned *)pFun, pPars->nVars );
1395 printf( "Generated symmetric function: %s\n", pPars->pTtStr );
1396 ABC_FREE( pFun );
1397 }
1398 if ( pPars->pTtStr )
1399 Abc_TtReadHex( pTruth, pPars->pTtStr );
1400 else assert( 0 );
1401 assert( pPars->nVars <= 10 );
1402 assert( pPars->nLutSize <= 6 );
1403 p = Exa3_ManAlloc( pPars, pTruth );
1404 if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, p->nWords ); }
1405 status = Exa3_ManAddCnfStart( p, pPars->fOnlyAnd );
1406 assert( status );
1407 printf( "Running exact synthesis for %d-input function with %d %d-input LUTs...\n", p->nVars, p->nNodes, p->nLutSize );
1408 for ( i = 0; iMint != -1; i++ )
1409 {
1410 abctime clk = Abc_Clock();
1411 if ( !Exa3_ManAddCnf( p, iMint ) )
1412 break;
1413 status = sat_solver_solve( p->pSat, NULL, NULL, 0, 0, 0, 0 );
1414 if ( pPars->fVerbose )
1415 {
1416 printf( "Iter %3d : ", i );
1417 Extra_PrintBinary( stdout, (unsigned *)&iMint, p->nVars );
1418 printf( " Var =%5d ", p->iVar );
1419 printf( "Cla =%6d ", sat_solver_nclauses(p->pSat) );
1420 printf( "Conf =%9d ", sat_solver_nconflicts(p->pSat) );
1421 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
1422 }
1423 if ( status == l_False )
1424 {
1425 printf( "The problem has no solution.\n" );
1426 break;
1427 }
1428 iMint = Exa3_ManEval( p );
1429 }
1430 if ( iMint == -1 )
1431 Exa3_ManPrintSolution( p, fCompl );
1432 Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
1433 if ( iMint == -1 )
1434 Exa3_ManDumpBlif( p, fCompl );
1435 if ( pPars->pSymStr )
1436 ABC_FREE( pPars->pTtStr );
1437 Exa3_ManFree( p );
1438}
1439
1440
1444
1445
1447
int nWords
Definition abcNpn.c:127
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
#define l_False
Definition bmcBmcS.c:36
void Exa3_ManExactSynthesis2(Bmc_EsPar_t *pPars)
Definition bmcMaj2.c:1385
int Maj_ManExactSynthesis2(int nVars, int nNodes, int fUseConst, int fUseLine, int fUseRand, int nRands, int fVerbose)
Definition bmcMaj2.c:462
#define MAJ_NOBJS
DECLARATIONS ///.
Definition bmcMaj2.c:33
int Maj_ManExactSynthesisTest()
Definition bmcMaj2.c:503
void Exa_ManExactSynthesis2(Bmc_EsPar_t *pPars)
Definition bmcMaj2.c:852
int Maj_ManValue(int iMint, int nVars)
FUNCTION DEFINITIONS ///.
Definition bmcMaj.c:80
void Maj_ManFree(Maj_Man_t *p)
Definition bmcMaj.c:164
Vec_Wrd_t * Exa_ManTruthTables(Exa_Man_t *p)
Definition bmcMaj.c:454
struct Maj_Man_t_ Maj_Man_t
Definition bmcMaj.c:46
Vec_Wrd_t * Maj_ManTruthTables(Maj_Man_t *p)
Definition bmcMaj.c:87
int Exa_ManMarkup(Exa_Man_t *p)
Definition bmcMaj.c:462
struct Exa3_Man_t_ Exa3_Man_t
Definition bmcMaj.c:994
struct Exa_Man_t_ Exa_Man_t
Definition bmcMaj.c:421
Exa_Man_t * Exa_ManAlloc(Bmc_EsPar_t *pPars, word *pTruth)
Definition bmcMaj.c:502
int Maj_ManAddCnf(Maj_Man_t *p, int iMint)
Definition bmcMaj.c:325
void Exa_ManPrintSolution(Exa_Man_t *p, int fCompl)
Definition bmcMaj.c:659
int Exa_ManAddCnf(Exa_Man_t *p, int iMint)
Definition bmcMaj.c:885
void Exa_ManFree(Exa_Man_t *p)
Definition bmcMaj.c:527
int Maj_ManMarkup(Maj_Man_t *p)
Definition bmcMaj.c:100
int Exa_ManAddCnfStart(Exa_Man_t *p, int fOnlyAnd)
Definition bmcMaj.c:764
Maj_Man_t * Maj_ManAlloc(int nVars, int nNodes, int fUseConst, int fUseLine)
Definition bmcMaj.c:147
void Maj_ManPrintSolution(Maj_Man_t *p)
Definition bmcMaj.c:244
int Maj_ManAddCnfStart(Maj_Man_t *p)
Definition bmcMaj.c:278
typedefABC_NAMESPACE_HEADER_START struct Bmc_EsPar_t_ Bmc_EsPar_t
INCLUDES ///.
Definition bmc.h:47
#define sat_solver_addclause
Definition cecSatG2.c:37
#define sat_solver
Definition cecSatG2.c:34
#define sat_solver_solve
Definition cecSatG2.c:45
Cube * p
Definition exorList.c:222
char * Extra_TimeStamp()
void Extra_PrintHexadecimalString(char *pString, unsigned Sign[], int nVars)
void Extra_PrintBinary(FILE *pFile, unsigned Sign[], int nBits)
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
sat_solver * sat_solver_new(void)
Definition satSolver.c:1137
int sat_solver_nconflicts(sat_solver *s)
Definition satSolver.c:2381
int sat_solver_nclauses(sat_solver *s)
Definition satSolver.c:2375
void sat_solver_setnvars(sat_solver *s, int n)
Definition satSolver.c:1272
void sat_solver_delete(sat_solver *s)
Definition satSolver.c:1341
word * pTruth
Definition bmcMaj.c:1005
Vec_Wrd_t * vInfo
Definition bmcMaj.c:1006
bmcg_sat_solver * pSat
Definition bmcMaj.c:1013
int nLutSize
Definition bmcMaj.c:1000
Vec_Wec_t * vOutLits
Definition bmcMaj.c:1011
int nVars
Definition bmcMaj.c:998
int VarMarks[MAJ_NOBJS][6][MAJ_NOBJS]
Definition bmcMaj.c:1009
int nNodes
Definition bmcMaj.c:999
int VarVals[MAJ_NOBJS]
Definition bmcMaj.c:1010
Bmc_EsPar_t * pPars
Definition bmcMaj.c:997
int LutMask
Definition bmcMaj.c:1001
word * pTruth
Definition bmcMaj.c:430
int nNodes
Definition bmcMaj.c:426
Bmc_EsPar_t * pPars
Definition bmcMaj.c:424
int VarMarks[MAJ_NOBJS][2][MAJ_NOBJS]
Definition bmcMaj.c:432
bmcg_sat_solver * pSat
Definition bmcMaj.c:435
int nVars
Definition bmcMaj.c:425
Vec_Wrd_t * vInfo
Definition bmcMaj.c:431
int nObjs
Definition bmcMaj.c:427
int VarVals[MAJ_NOBJS]
Definition bmcMaj.c:433
int nWords
Definition bmcMaj.c:428
int iVar
Definition bmcMaj.c:429
Vec_Wec_t * vOutLits
Definition bmcMaj.c:434
Vec_Wrd_t * vInfo
Definition bmcMaj.c:56
int fVerbose
Definition bmcMaj2.c:47
int iVar
Definition bmcMaj.c:53
int nRands
Definition bmcMaj2.c:46
int nVars
Definition bmcMaj.c:49
Vec_Wec_t * vOutLits
Definition bmcMaj.c:59
int VarVals[MAJ_NOBJS+2]
Definition bmcMaj.c:58
int nObjs
Definition bmcMaj.c:51
int fUseConst
Definition bmcMaj.c:54
int nNodes
Definition bmcMaj.c:50
int fUseLine
Definition bmcMaj.c:55
int fUseRand
Definition bmcMaj2.c:45
int VarMarks[MAJ_NOBJS][3][MAJ_NOBJS]
Definition bmcMaj.c:57
bmcg_sat_solver * pSat
Definition bmcMaj.c:60
#define MAJ_NOBJS
#define assert(ex)
Definition util_old.h:213
char * sprintf()
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition vecWec.h:42
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition vecWrd.h:42