ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcCascade.c
Go to the documentation of this file.
1
20
21#include "base/abc/abc.h"
22
23#ifdef ABC_USE_CUDD
24#include "bdd/reo/reo.h"
25#include "bdd/extrab/extraBdd.h"
26#endif
27
29
33
34#ifdef ABC_USE_CUDD
35
36#define BDD_FUNC_MAX 256
37
38//extern void Abc_NodeShowBddOne( DdManager * dd, DdNode * bFunc );
39extern DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, DdNode ** pbVars );
40
44
56DdNode * Abc_ResBuildBdd( Abc_Ntk_t * pNtk, DdManager * dd )
57{
58 Vec_Ptr_t * vNodes, * vBdds, * vLocals;
59 Abc_Obj_t * pObj, * pFanin;
60 DdNode * bFunc, * bPart, * bTemp, * bVar;
61 int i, k;
62 assert( Abc_NtkIsSopLogic(pNtk) );
63 assert( Abc_NtkCoNum(pNtk) <= 3 );
64 vBdds = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
65 Abc_NtkForEachCi( pNtk, pObj, i )
66 Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), Cudd_bddIthVar(dd, i) );
67 // create internal node BDDs
68 vNodes = Abc_NtkDfs( pNtk, 0 );
69 vLocals = Vec_PtrAlloc( 6 );
70 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
71 {
72 if ( Abc_ObjFaninNum(pObj) == 0 )
73 {
74 bFunc = Cudd_NotCond( Cudd_ReadOne(dd), Abc_SopIsConst0((char *)pObj->pData) ); Cudd_Ref( bFunc );
75 Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), bFunc );
76 continue;
77 }
78 Vec_PtrClear( vLocals );
79 Abc_ObjForEachFanin( pObj, pFanin, k )
80 Vec_PtrPush( vLocals, Vec_PtrEntry(vBdds, Abc_ObjId(pFanin)) );
81 bFunc = Abc_ConvertSopToBdd( dd, (char *)pObj->pData, (DdNode **)Vec_PtrArray(vLocals) ); Cudd_Ref( bFunc );
82 Vec_PtrWriteEntry( vBdds, Abc_ObjId(pObj), bFunc );
83 }
84 Vec_PtrFree( vLocals );
85 // create char function
86 bFunc = Cudd_ReadOne( dd ); Cudd_Ref( bFunc );
87 Abc_NtkForEachCo( pNtk, pObj, i )
88 {
89 bVar = Cudd_bddIthVar( dd, i + Abc_NtkCiNum(pNtk) );
90 bTemp = (DdNode *)Vec_PtrEntry( vBdds, Abc_ObjFaninId0(pObj) );
91 bPart = Cudd_bddXnor( dd, bTemp, bVar ); Cudd_Ref( bPart );
92 bFunc = Cudd_bddAnd( dd, bTemp = bFunc, bPart ); Cudd_Ref( bFunc );
93 Cudd_RecursiveDeref( dd, bTemp );
94 Cudd_RecursiveDeref( dd, bPart );
95 }
96 // dereference
97 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
98 Cudd_RecursiveDeref( dd, (DdNode *)Vec_PtrEntry(vBdds, Abc_ObjId(pObj)) );
99 Vec_PtrFree( vBdds );
100 Vec_PtrFree( vNodes );
101 // reorder
102 Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 );
103 Cudd_Deref( bFunc );
104 return bFunc;
105}
106
118void Abc_ResStartPart( int nInputs, unsigned uParts[], int nParts )
119{
120 int i, Group, Left, Shift = 0, Count = 0;
121 Group = nInputs / nParts;
122 Left = nInputs % nParts;
123 for ( i = 0; i < Left; i++ )
124 {
125 uParts[i] = (~((~0) << (Group+1))) << Shift;
126 Shift += Group+1;
127 }
128 for ( ; i < nParts; i++ )
129 {
130 uParts[i] = (~((~0) << Group)) << Shift;
131 Shift += Group;
132 }
133 for ( i = 0; i < nParts; i++ )
134 Count += Extra_WordCountOnes( uParts[i] );
135 assert( Count == nInputs );
136}
137
149void Abc_ResStartPart2( int nInputs, unsigned uParts[], int nParts )
150{
151 int i, Count = 0;
152 for ( i = 0; i < nParts; i++ )
153 uParts[i] = 0;
154 for ( i = 0; i < nInputs; i++ )
155 uParts[i % nParts] |= (1 << i);
156 for ( i = 0; i < nParts; i++ )
157 Count += Extra_WordCountOnes( uParts[i] );
158 assert( Count == nInputs );
159}
160
172int Abc_ResCheckUnique( char Pats[], int nPats, int pat )
173{
174 int i;
175 for ( i = 0; i < nPats; i++ )
176 if ( Pats[i] == pat )
177 return 0;
178 return 1;
179}
180
192int Abc_ResCheckNonStrict( char Pattern[], int nVars, int nBits )
193{
194 static char Pat0[256], Pat1[256];
195 int v, m, nPats0, nPats1, nNumber = (1 << (nBits - 1));
196 int Result = 0;
197 for ( v = 0; v < nVars; v++ )
198 {
199 nPats0 = nPats1 = 0;
200 for ( m = 0; m < (1<<nVars); m++ )
201 {
202 if ( (m & (1 << v)) == 0 )
203 {
204 if ( Abc_ResCheckUnique( Pat0, nPats0, Pattern[m] ) )
205 {
206 Pat0[ nPats0++ ] = Pattern[m];
207 if ( nPats0 > nNumber )
208 break;
209 }
210 }
211 else
212 {
213 if ( Abc_ResCheckUnique( Pat1, nPats1, Pattern[m] ) )
214 {
215 Pat1[ nPats1++ ] = Pattern[m];
216 if ( nPats1 > nNumber )
217 break;
218 }
219 }
220 }
221 if ( m == (1<<nVars) )
222 Result++;
223 }
224 return Result;
225}
226
238int Abc_ResCofCount( DdManager * dd, DdNode * bFunc, unsigned uMask, int * pCheck )
239{
240 static char Pattern[256];
241 DdNode * pbVars[32];
242 Vec_Ptr_t * vCofs;
243 DdNode * bCof, * bCube, * bTemp;
244 int i, k, Result, nVars = 0;
245 // collect variables
246 for ( i = 0; i < 32; i++ )
247 if ( uMask & (1 << i) )
248 pbVars[nVars++] = dd->vars[i];
249 assert( nVars <= 8 );
250 // compute cofactors
251 vCofs = Vec_PtrAlloc( 100 );
252 for ( i = 0; i < (1 << nVars); i++ )
253 {
254 bCube = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 ); Cudd_Ref( bCube );
255 bCof = Cudd_Cofactor( dd, bFunc, bCube ); Cudd_Ref( bCof );
256 Cudd_RecursiveDeref( dd, bCube );
257 Vec_PtrForEachEntry( DdNode *, vCofs, bTemp, k )
258 if ( bTemp == bCof )
259 break;
260 if ( k < Vec_PtrSize(vCofs) )
261 Cudd_RecursiveDeref( dd, bCof );
262 else
263 Vec_PtrPush( vCofs, bCof );
264 Pattern[i] = k;
265 }
266 Result = Vec_PtrSize( vCofs );
267 Vec_PtrForEachEntry( DdNode *, vCofs, bCof, i )
268 Cudd_RecursiveDeref( dd, bCof );
269 Vec_PtrFree( vCofs );
270 if ( pCheck )
271 {
272 *pCheck = Abc_ResCheckNonStrict( Pattern, nVars, Abc_Base2Log(Result) );
273/*
274 if ( *pCheck == 1 && nVars == 4 && Result == 8 )
275 {
276 for ( i = 0; i < (1 << nVars); i++ )
277 printf( "%d ", Pattern[i] );
278 i = 0;
279 }
280*/
281 }
282 return Result;
283}
284
296int Abc_ResCost( DdManager * dd, DdNode * bFunc, unsigned uMask, int * pnCofs, int * pCheck )
297{
298 int nCofs = Abc_ResCofCount( dd, bFunc, uMask, pCheck );
299 int n2Log = Abc_Base2Log( nCofs );
300 if ( pnCofs ) *pnCofs = nCofs;
301 return 10000 * n2Log + (nCofs - (1 << (n2Log-1))) * (nCofs - (1 << (n2Log-1)));
302}
303
315int Abc_ResMigrate( DdManager * dd, DdNode * bFunc, int nInputs, unsigned uParts[], int iPart1, int iPart2 )
316{
317 unsigned uParts2[2] = { uParts[iPart1], uParts[iPart2] };
318 int i, k, CostCur, CostBest, fChange = 0;
319 assert( (uParts[iPart1] & uParts[iPart2]) == 0 );
320 CostBest = Abc_ResCost( dd, bFunc, uParts[iPart1], NULL, NULL )
321 + Abc_ResCost( dd, bFunc, uParts[iPart2], NULL, NULL );
322 for ( i = 0; i < nInputs; i++ )
323 if ( uParts[iPart1] & (1 << i) )
324 {
325 for ( k = 0; k < nInputs; k++ )
326 if ( uParts[iPart2] & (1 << k) )
327 {
328 if ( i == k )
329 continue;
330 uParts[iPart1] ^= (1 << i) | (1 << k);
331 uParts[iPart2] ^= (1 << i) | (1 << k);
332 CostCur = Abc_ResCost( dd, bFunc, uParts[iPart1], NULL, NULL ) + Abc_ResCost( dd, bFunc, uParts[iPart2], NULL, NULL );
333 if ( CostCur < CostBest )
334 {
335 CostCur = CostBest;
336 uParts2[0] = uParts[iPart1];
337 uParts2[1] = uParts[iPart2];
338 fChange = 1;
339 }
340 uParts[iPart1] ^= (1 << i) | (1 << k);
341 uParts[iPart2] ^= (1 << i) | (1 << k);
342 }
343 }
344 uParts[iPart1] = uParts2[0];
345 uParts[iPart2] = uParts2[1];
346 return fChange;
347}
348
360void Abc_ResPrint( DdManager * dd, DdNode * bFunc, int nInputs, unsigned uParts[], int nParts )
361{
362 int i, k, nCofs, Cost, CostAll = 0, fCheck;
363 for ( i = 0; i < nParts; i++ )
364 {
365 Cost = Abc_ResCost( dd, bFunc, uParts[i], &nCofs, &fCheck );
366 CostAll += Cost;
367 for ( k = 0; k < nInputs; k++ )
368 printf( "%c", (uParts[i] & (1 << k))? 'a' + k : '-' );
369 printf( " %2d %d-%d %6d ", nCofs, Abc_Base2Log(nCofs), fCheck, Cost );
370 }
371 printf( "%4d\n", CostAll );
372}
373
385void Abc_ResPrintAllCofs( DdManager * dd, DdNode * bFunc, int nInputs, int nCofMax )
386{
387 int i, k, nBits, nCofs, Cost, fCheck;
388 for ( i = 0; i < (1<<nInputs); i++ )
389 {
390 nBits = Extra_WordCountOnes( i );
391 if ( nBits < 3 || nBits > 6 )
392 continue;
393 Cost = Abc_ResCost( dd, bFunc, i, &nCofs, &fCheck );
394 if ( nCofs > nCofMax )
395 continue;
396 for ( k = 0; k < nInputs; k++ )
397 printf( "%c", (i & (1 << k))? 'a' + k : '-' );
398 printf( " n=%2d c=%2d l=%d-%d %6d\n",
399 Extra_WordCountOnes(i), nCofs, Abc_Base2Log(nCofs), fCheck, Cost );
400 }
401}
402
414void Abc_ResSwapRandom( DdManager * dd, DdNode * bFunc, int nInputs, unsigned uParts[], int nParts, int nTimes )
415{
416 int i, k, n, iPart1, iPart2;
417 for ( n = 0; n < nTimes; )
418 {
419 // get the vars
420 i = k = 0;
421 while ( i == k )
422 {
423 i = rand() % nInputs;
424 k = rand() % nInputs;
425 }
426 // find the groups
427 for ( iPart1 = 0; iPart1 < nParts; iPart1++ )
428 if ( uParts[iPart1] & (1 << i) )
429 break;
430 for ( iPart2 = 0; iPart2 < nParts; iPart2++ )
431 if ( uParts[iPart2] & (1 << k) )
432 break;
433 if ( iPart1 == iPart2 )
434 continue;
435 // swap the vars
436 uParts[iPart1] ^= (1 << i) | (1 << k);
437 uParts[iPart2] ^= (1 << i) | (1 << k);
438 n++;
439//printf( " " );
440//Abc_ResPrint( dd, bFunc, nInputs, uParts, nParts );
441 }
442}
443
455void Abc_ResPartition( DdManager * dd, DdNode * bFunc, int nInputs )
456{
457 int nIters = 5;
458 unsigned uParts[10];
459 int i, fChange = 1;
460 int nSuppSize = Cudd_SupportSize( dd, bFunc );
461 printf( "Ins =%3d. Outs =%2d. Nodes =%3d. Supp =%2d.\n",
462 nInputs, dd->size-nInputs, Cudd_DagSize(bFunc), nSuppSize );
463//Abc_ResPrintAllCofs( dd, bFunc, nInputs, 4 );
464
465 if ( nSuppSize <= 6 )
466 {
467 printf( "Support is less or equal than 6\n" );
468 return;
469 }
470 if ( nInputs <= 12 )
471 {
472 Abc_ResStartPart( nInputs, uParts, 2 );
473 Abc_ResPrint( dd, bFunc, nInputs, uParts, 2 );
474 for ( i = 0; i < nIters; i++ )
475 {
476 if ( i )
477 {
478 printf( "Randomizing... \n" );
479 Abc_ResSwapRandom( dd, bFunc, nInputs, uParts, 2, 20 );
480 Abc_ResPrint( dd, bFunc, nInputs, uParts, 2 );
481 }
482 fChange = 1;
483 while ( fChange )
484 {
485 fChange = Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 1 );
486 Abc_ResPrint( dd, bFunc, nInputs, uParts, 2 );
487 }
488 }
489 }
490 else if ( nInputs > 12 && nInputs <= 18 )
491 {
492 Abc_ResStartPart( nInputs, uParts, 3 );
493 Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 );
494 for ( i = 0; i < nIters; i++ )
495 {
496 if ( i )
497 {
498 printf( "Randomizing... \n" );
499 Abc_ResSwapRandom( dd, bFunc, nInputs, uParts, 3, 20 );
500 Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 );
501 }
502 fChange = 1;
503 while ( fChange )
504 {
505 fChange = Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 1 );
506 Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 );
507 fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 2 );
508 Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 );
509 fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 1, 2 );
510 Abc_ResPrint( dd, bFunc, nInputs, uParts, 3 );
511 }
512 }
513 }
514 else if ( nInputs > 18 && nInputs <= 24 )
515 {
516 Abc_ResStartPart( nInputs, uParts, 4 );
517 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
518 for ( i = 0; i < nIters; i++ )
519 {
520 if ( i )
521 {
522 printf( "Randomizing... \n" );
523 Abc_ResSwapRandom( dd, bFunc, nInputs, uParts, 4, 20 );
524 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
525 }
526 fChange = 1;
527 while ( fChange )
528 {
529 fChange = Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 1 );
530 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
531 fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 2 );
532 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
533 fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 0, 3 );
534 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
535 fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 1, 2 );
536 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
537 fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 1, 3 );
538 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
539 fChange |= Abc_ResMigrate( dd, bFunc, nInputs, uParts, 2, 3 );
540 Abc_ResPrint( dd, bFunc, nInputs, uParts, 4 );
541 }
542 }
543 }
544// else assert( 0 );
545}
546
558void Abc_ResPartitionTest( Abc_Ntk_t * pNtk )
559{
560 DdManager * dd;
561 DdNode * bFunc;
562 dd = Cudd_Init( Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
563 bFunc = Abc_ResBuildBdd( pNtk, dd ); Cudd_Ref( bFunc );
564 Abc_ResPartition( dd, bFunc, Abc_NtkCiNum(pNtk) );
565 Cudd_RecursiveDeref( dd, bFunc );
566 Extra_StopManager( dd );
567}
568
569
570
571
572
573
574
586int Abc_NtkBddCofCount( DdManager * dd, DdNode * bFunc, DdNode ** pbVars, int nVars )
587{
588 Vec_Ptr_t * vCofs;
589 DdNode * bCof, * bCube;
590 int i, Result;
591 vCofs = Vec_PtrAlloc( 100 );
592 for ( i = 0; i < (1 << nVars); i++ )
593 {
594 bCube = Extra_bddBitsToCube( dd, i, nVars, pbVars, 1 ); Cudd_Ref( bCube );
595 bCof = Cudd_Cofactor( dd, bFunc, bCube ); Cudd_Ref( bCof );
596 Cudd_RecursiveDeref( dd, bCube );
597 if ( Vec_PtrPushUnique( vCofs, bCof ) )
598 Cudd_RecursiveDeref( dd, bCof );
599 }
600 Result = Vec_PtrSize( vCofs );
601 Vec_PtrForEachEntry( DdNode *, vCofs, bCof, i )
602 Cudd_RecursiveDeref( dd, bCof );
603 Vec_PtrFree( vCofs );
604 return Result;
605}
606
618void Abc_NtkExploreCofs2( DdManager * dd, DdNode * bFunc, DdNode ** pbVars, int nIns, int nLutSize )
619{
620 int i;
621 printf( "Inputs = %2d. Nodes = %2d. LutSize = %2d.\n", nIns, Cudd_DagSize(bFunc), nLutSize );
622 for ( i = 0; i <= nIns - nLutSize; i++ )
623 printf( "[%2d %2d] : %3d\n", i, i+nLutSize-1, Abc_NtkBddCofCount(dd, bFunc, dd->vars+i, nLutSize) );
624}
625
637void Abc_NtkExploreCofs( DdManager * dd, DdNode * bFunc, DdNode ** pbVars, int nIns, int nLutSize )
638{
639 DdManager * ddNew;
640 DdNode * bFuncNew;
641 DdNode * pbVarsNew[32];
642 int i, k, c, nCofs, nBits;
643
644 ddNew = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
645 Cudd_ShuffleHeap( ddNew, dd->invperm );
646 bFuncNew = Cudd_bddTransfer( dd, ddNew, bFunc ); Cudd_Ref( bFuncNew );
647
648 for ( i = 0; i < (1 << nIns); i++ )
649 {
650 nBits = Extra_WordCountOnes(i);
651 if ( nBits != nLutSize && nBits != nLutSize -1 && nBits != nLutSize -2 )
652 continue;
653 for ( c = k = 0; k < nIns; k++ )
654 {
655 if ( (i & (1 << k)) == 0 )
656 continue;
657// pbVarsNew[c++] = pbVars[k];
658 pbVarsNew[c++] = ddNew->vars[k];
659 }
660 nCofs = Abc_NtkBddCofCount(ddNew, bFuncNew, pbVarsNew, c);
661 if ( nCofs > 8 )
662 continue;
663
664 for ( c = k = 0; k < nIns; k++ )
665 {
666 if ( (i & (1 << k)) == 0 )
667 {
668 printf( "-" );
669 continue;
670 }
671 printf( "%c", k + 'a' );
672 }
673 printf( " : %2d\n", nCofs );
674 }
675
676 Cudd_RecursiveDeref( ddNew, bFuncNew );
677 Extra_StopManager( ddNew );
678}
679
691DdNode * Abc_NtkBddFindAddConst( DdManager * dd, DdNode * bFunc, int nOuts )
692{
693 int i, TermMask = 0;
694 DdNode * bFunc0, * bFunc1, * bConst0, * bConst1;
695 bConst0 = Cudd_ReadLogicZero( dd );
696 bConst1 = Cudd_ReadOne( dd );
697 for ( i = 0; i < nOuts; i++ )
698 {
699 if ( Cudd_IsComplement(bFunc) )
700 {
701 bFunc0 = Cudd_Not(Cudd_E(bFunc));
702 bFunc1 = Cudd_Not(Cudd_T(bFunc));
703 }
704 else
705 {
706 bFunc0 = Cudd_E(bFunc);
707 bFunc1 = Cudd_T(bFunc);
708 }
709 assert( bFunc0 == bConst0 || bFunc1 == bConst0 );
710 if ( bFunc0 == bConst0 )
711 {
712 TermMask ^= (1 << i);
713 bFunc = bFunc1;
714 }
715 else
716 bFunc = bFunc0;
717 }
718 assert( bFunc == bConst1 );
719 return Cudd_addConst( dd, TermMask );
720}
721
733DdNode * Abc_NtkBddToAdd_rec( DdManager * dd, DdNode * bFunc, int nOuts, stmm_table * tTable, int fCompl )
734{
735 DdNode * aFunc0, * aFunc1, * aFunc;
736 DdNode ** ppSlot;
737 assert( !Cudd_IsComplement(bFunc) );
738 if ( stmm_find_or_add( tTable, (char *)bFunc, (char ***)&ppSlot ) )
739 return *ppSlot;
740 if ( (int)bFunc->index >= Cudd_ReadSize(dd) - nOuts )
741 {
742 assert( Cudd_ReadPerm(dd, bFunc->index) >= Cudd_ReadSize(dd) - nOuts );
743 aFunc = Abc_NtkBddFindAddConst( dd, Cudd_NotCond(bFunc, fCompl), nOuts ); Cudd_Ref( aFunc );
744 }
745 else
746 {
747 aFunc0 = Abc_NtkBddToAdd_rec( dd, Cudd_Regular(cuddE(bFunc)), nOuts, tTable, fCompl ^ Cudd_IsComplement(cuddE(bFunc)) );
748 aFunc1 = Abc_NtkBddToAdd_rec( dd, cuddT(bFunc), nOuts, tTable, fCompl );
749 aFunc = Cudd_addIte( dd, Cudd_addIthVar(dd, bFunc->index), aFunc1, aFunc0 ); Cudd_Ref( aFunc );
750 }
751 return (*ppSlot = aFunc);
752}
753
765DdNode * Abc_NtkBddToAdd( DdManager * dd, DdNode * bFunc, int nOuts )
766{
767 DdNode * aFunc, * aTemp, * bTemp;
768 stmm_table * tTable;
769 stmm_generator * gen;
771 aFunc = Abc_NtkBddToAdd_rec( dd, Cudd_Regular(bFunc), nOuts, tTable, Cudd_IsComplement(bFunc) );
772 stmm_foreach_item( tTable, gen, (char **)&bTemp, (char **)&aTemp )
773 Cudd_RecursiveDeref( dd, aTemp );
774 stmm_free_table( tTable );
775 Cudd_Deref( aFunc );
776 return aFunc;
777}
778
790DdNode * Abc_NtkAddToBdd_rec( DdManager * dd, DdNode * aFunc, int nIns, int nOuts, stmm_table * tTable )
791{
792 DdNode * bFunc0, * bFunc1, * bFunc;
793 DdNode ** ppSlot;
794 assert( !Cudd_IsComplement(aFunc) );
795 if ( stmm_find_or_add( tTable, (char *)aFunc, (char ***)&ppSlot ) )
796 return *ppSlot;
797 if ( Cudd_IsConstant(aFunc) )
798 {
799 assert( Cudd_ReadSize(dd) >= nIns + nOuts );
800 bFunc = Extra_bddBitsToCube( dd, (int)Cudd_V(aFunc), nOuts, dd->vars + nIns, 1 ); Cudd_Ref( bFunc );
801 }
802 else
803 {
804 assert( aFunc->index < nIns );
805 bFunc0 = Abc_NtkAddToBdd_rec( dd, cuddE(aFunc), nIns, nOuts, tTable );
806 bFunc1 = Abc_NtkAddToBdd_rec( dd, cuddT(aFunc), nIns, nOuts, tTable );
807 bFunc = Cudd_bddIte( dd, Cudd_bddIthVar(dd, aFunc->index), bFunc1, bFunc0 ); Cudd_Ref( bFunc );
808 }
809 return (*ppSlot = bFunc);
810}
811
823DdNode * Abc_NtkAddToBdd( DdManager * dd, DdNode * aFunc, int nIns, int nOuts )
824{
825 DdNode * bFunc, * bTemp, * aTemp;
826 stmm_table * tTable;
827 stmm_generator * gen;
829 bFunc = Abc_NtkAddToBdd_rec( dd, aFunc, nIns, nOuts, tTable );
830 stmm_foreach_item( tTable, gen, (char **)&aTemp, (char **)&bTemp )
831 Cudd_RecursiveDeref( dd, bTemp );
832 stmm_free_table( tTable );
833 Cudd_Deref( bFunc );
834 return bFunc;
835}
836
848DdNode * Abc_NtkBddDecCharFunc( DdManager * dd, DdNode ** pFuncs, int nOuts, int Mask, int nBits )
849{
850 DdNode * bFunc, * bTemp, * bExor, * bVar;
851 int i, Count = 0;
852 bFunc = Cudd_ReadOne( dd ); Cudd_Ref( bFunc );
853 for ( i = 0; i < nOuts; i++ )
854 {
855 if ( (Mask & (1 << i)) == 0 )
856 continue;
857 Count++;
858 bVar = Cudd_bddIthVar( dd, dd->size - nOuts + i );
859 bExor = Cudd_bddXor( dd, pFuncs[i], bVar ); Cudd_Ref( bExor );
860 bFunc = Cudd_bddAnd( dd, bTemp = bFunc, Cudd_Not(bExor) ); Cudd_Ref( bFunc );
861 Cudd_RecursiveDeref( dd, bTemp );
862 Cudd_RecursiveDeref( dd, bExor );
863 }
864 Cudd_Deref( bFunc );
865 assert( Count == nBits );
866 return bFunc;
867}
868
880DdNode * Abc_NtkBddDecTry( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nIns, int nOuts, int Mask, int nBits )
881{
882// int fReorder = 0;
883 DdNode * bFunc;//, * aFunc, * aFuncNew;
884 // derive the characteristic function
885 bFunc = Abc_NtkBddDecCharFunc( dd, pFuncs, nOuts, Mask, nBits ); Cudd_Ref( bFunc );
886/*
887 // transfer to ADD
888 aFunc = Abc_NtkBddToAdd( dd, bFunc, nOuts ); Cudd_Ref( aFunc );
889 Cudd_RecursiveDeref( dd, bFunc );
890//Abc_NodeShowBddOne( dd, aFunc );
891
892 // perform reordering for BDD width
893 if ( fReorder )
894 {
895 aFuncNew = Extra_Reorder( pReo, dd, aFunc, NULL ); Cudd_Ref( aFuncNew );
896 printf( "Before = %d. After = %d.\n", Cudd_DagSize(aFunc), Cudd_DagSize(aFuncNew) );
897 Cudd_RecursiveDeref( dd, aFunc );
898 }
899 else
900 aFuncNew = aFunc;
901
902 // get back to BDD
903 bFunc = Abc_NtkAddToBdd( dd, aFuncNew, nIns, nOuts ); Cudd_Ref( bFunc );
904 Cudd_RecursiveDeref( dd, aFuncNew );
905//Abc_NodeShowBddOne( dd, bFunc );
906 // print the result
907// reoProfileWidthPrint( pReo );
908*/
909 Cudd_Deref( bFunc );
910 return bFunc;
911}
912
924DdNode * Abc_NtkBddDecInt( reo_man * pReo, DdManager * dd, DdNode ** pFuncs, int nIns, int nOuts )
925{
926/*
927 int i, k;
928 for ( i = 1; i <= nOuts; i++ )
929 {
930 for ( k = 0; k < (1<<nOuts); k++ )
931 if ( Extra_WordCountOnes(k) == i )
932 {
933 Extra_PrintBinary( stdout, (unsigned *)&k, nOuts );
934 Abc_NtkBddDecTry( pReo, dd, pFuncs, nOuts, k, i );
935 printf( "\n" );
936 }
937 }
938*/
939 return Abc_NtkBddDecTry( pReo, dd, pFuncs, nIns, nOuts, ~(1<<(32-nOuts)), nOuts );
940
941}
942
954Abc_Ntk_t * Abc_NtkCreateFromCharFunc( Abc_Ntk_t * pNtk, DdManager * dd, DdNode * bFunc )
955{
956 Abc_Ntk_t * pNtkNew;
957 Abc_Obj_t * pNode, * pNodeNew, * pNodePo;
958 int i;
959 // start the network
960 pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_BDD, 1 );
961 pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
962 // create inputs for CIs
963 pNodeNew = Abc_NtkCreateNode( pNtkNew );
964 Abc_NtkForEachCi( pNtk, pNode, i )
965 {
966 pNode->pCopy = Abc_NtkCreatePi( pNtkNew );
967 Abc_ObjAddFanin( pNodeNew, pNode->pCopy );
968 Abc_ObjAssignName( pNode->pCopy, Abc_ObjName(pNode), NULL );
969 }
970 // create inputs for COs
971 Abc_NtkForEachCo( pNtk, pNode, i )
972 {
973 pNode->pCopy = Abc_NtkCreatePi( pNtkNew );
974 Abc_ObjAddFanin( pNodeNew, pNode->pCopy );
975 Abc_ObjAssignName( pNode->pCopy, Abc_ObjName(pNode), NULL );
976 }
977 // transfer BDD
978 pNodeNew->pData = Extra_TransferLevelByLevel( dd, (DdManager *)pNtkNew->pManFunc, bFunc ); Cudd_Ref( (DdNode *)pNodeNew->pData );
979 // transfer BDD into to be the local function
980 pNodePo = Abc_NtkCreatePo( pNtkNew );
981 Abc_ObjAddFanin( pNodePo, pNodeNew );
982 Abc_ObjAssignName( pNodePo, "out", NULL );
983 if ( !Abc_NtkCheck( pNtkNew ) )
984 fprintf( stdout, "Abc_NtkCreateFromCharFunc(): Network check has failed.\n" );
985 return pNtkNew;
986}
987
999Abc_Ntk_t * Abc_NtkBddDec( Abc_Ntk_t * pNtk, int fVerbose )
1000{
1001 int nBddSizeMax = 1000000;
1002 int fDropInternal = 0;
1003 int fReorder = 1;
1004 Abc_Ntk_t * pNtkNew;
1005 reo_man * pReo;
1006 DdManager * dd;
1007 DdNode * pFuncs[BDD_FUNC_MAX];
1008 DdNode * bFunc;
1009 Abc_Obj_t * pNode;
1010 int i;
1011 assert( Abc_NtkIsStrash(pNtk) );
1012 assert( Abc_NtkCoNum(pNtk) <= BDD_FUNC_MAX );
1013 dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddSizeMax, fDropInternal, fReorder, 0, fVerbose );
1014 if ( dd == NULL )
1015 {
1016 Abc_Print( -1, "Construction of global BDDs has failed.\n" );
1017 return NULL;
1018 }
1019 // collect global BDDs
1020 Abc_NtkForEachCo( pNtk, pNode, i )
1021 pFuncs[i] = (DdNode *)Abc_ObjGlobalBdd(pNode);
1022
1023 // create new variables at the bottom
1024 assert( dd->size == Abc_NtkCiNum(pNtk) );
1025 for ( i = 0; i < Abc_NtkCoNum(pNtk); i++ )
1026 Cudd_addNewVarAtLevel( dd, dd->size );
1027
1028 // prepare reordering engine
1029 pReo = Extra_ReorderInit( Abc_NtkCiNum(pNtk), 1000 );
1032 Extra_ReorderSetVerbosity( pReo, 1 );
1033
1034 // derive characteristic function
1035 bFunc = Abc_NtkBddDecInt( pReo, dd, pFuncs, Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk) ); Cudd_Ref( bFunc );
1036 Extra_ReorderQuit( pReo );
1037
1038Abc_NtkExploreCofs( dd, bFunc, dd->vars, Abc_NtkCiNum(pNtk), 6 );
1039
1040 // create new network
1041// pNtkNew = Abc_NtkCreateFromCharFunc( pNtk, dd, bFunc );
1042 pNtkNew = Abc_NtkDup( pNtk );
1043
1044 // cleanup
1045 Cudd_RecursiveDeref( dd, bFunc );
1046 Abc_NtkFreeGlobalBdds( pNtk, 1 );
1047 return pNtkNew;
1048}
1049
1050#else
1051
1052Abc_Ntk_t * Abc_NtkBddDec( Abc_Ntk_t * pNtk, int fVerbose ) { return NULL; }
1053
1054#endif
1055
1057
1061
1062
ABC_NAMESPACE_IMPL_START Abc_Ntk_t * Abc_NtkBddDec(Abc_Ntk_t *pNtk, int fVerbose)
DECLARATIONS ///.
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition abc.h:522
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
Definition abcNtk.c:53
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
Definition abcFanio.c:84
ABC_DLL int Abc_SopIsConst0(char *pSop)
Definition abcSop.c:724
ABC_DLL Vec_Ptr_t * Abc_NtkDfs(Abc_Ntk_t *pNtk, int fCollectAll)
Definition abcDfs.c:82
ABC_DLL int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
Definition abcCheck.c:64
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
Definition abcNames.c:69
@ ABC_NTK_LOGIC
Definition abc.h:57
ABC_DLL void * Abc_NtkFreeGlobalBdds(Abc_Ntk_t *pNtk, int fFreeMan)
ABC_DLL void * Abc_NtkBuildGlobalBdds(Abc_Ntk_t *pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose)
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition abc.h:518
@ ABC_FUNC_BDD
Definition abc.h:66
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
Definition abcNtk.c:472
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
DdNode * Extra_bddBitsToCube(DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
void Extra_StopManager(DdManager *dd)
DdNode * Extra_TransferLevelByLevel(DdManager *ddSource, DdManager *ddDestination, DdNode *f)
char * Extra_UtilStrsav(const char *s)
struct _reo_man reo_man
Definition reo.h:63
void Extra_ReorderQuit(reo_man *p)
Definition reoApi.c:79
reo_man * Extra_ReorderInit(int nDdVarsMax, int nNodesMax)
FUNCTION DECLARATIONS ///.
Definition reoApi.c:50
@ REO_MINIMIZE_WIDTH
Definition reo.h:52
void Extra_ReorderSetVerbosity(reo_man *p, int fVerbose)
Definition reoApi.c:229
void Extra_ReorderSetMinimizationType(reo_man *p, reo_min_type fMinType)
Definition reoApi.c:122
void Extra_ReorderSetVerification(reo_man *p, int fVerify)
Definition reoApi.c:212
int st__ptrhash(const char *, int)
Definition st.c:467
int st__ptrcmp(const char *, const char *)
Definition st.c:479
int stmm_find_or_add(stmm_table *table, char *key, char ***slot)
Definition stmm.c:266
void stmm_free_table(stmm_table *table)
Definition stmm.c:79
stmm_table * stmm_init_table(stmm_compare_func_type compare, stmm_hash_func_type hash)
Definition stmm.c:69
#define stmm_foreach_item(table, gen, key, value)
Definition stmm.h:121
char * pName
Definition abc.h:158
void * pManFunc
Definition abc.h:191
void * pData
Definition abc.h:145
Abc_Obj_t * pCopy
Definition abc.h:148
#define assert(ex)
Definition util_old.h:213
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55