61 assert( Abc_ObjIsNode(pObj) && Abc_ObjIsNode(pPivot) );
63 Vec_PtrClear( vFanins );
65 if ( pFanin != pPivot )
66 Vec_PtrPush( vFanins, pFanin );
70 Vec_PtrPushUnique( vFanins, pFanin );
71 if ( Vec_PtrSize(vFanins) > nLutSize )
88void Abc_NtkCheckAbsorb(
Abc_Ntk_t * pNtk,
int nLutSize )
93 int i, k, Counter = 0, Counter2 = 0;
95 vCounts = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
96 vFanins = Vec_PtrAlloc( 100 );
99 if ( Abc_ObjIsNode(pFanin) && Abc_ObjCheckAbsorb( pObj, pFanin, nLutSize, vFanins ) )
101 Vec_IntAddToEntry( vCounts, Abc_ObjId(pFanin), 1 );
104 Vec_PtrFree( vFanins );
106 if ( Vec_IntEntry(vCounts, Abc_ObjId(pObj)) == Abc_ObjFanoutNum(pObj) )
111 printf(
"Absorted = %6d. (%6.2f %%) Fully = %6d. (%6.2f %%) ",
112 Counter, 100.0 * Counter / Abc_NtkNodeNum(pNtk),
113 Counter2, 100.0 * Counter2 / Abc_NtkNodeNum(pNtk) );
114 Abc_PrintTime( 1,
"Time", Abc_Clock() - clk );
115 Vec_IntFree( vCounts );
131 DdManager * dd = (DdManager *)pNtkNew->
pManFunc;
133 DdNode * bSpin, * bCof0, * bCof1;
134 pNode = Abc_NtkCreateNode( pNtkNew );
138 bSpin = Cudd_bddIthVar(dd, 0);
139 bCof0 = Cudd_bddIthVar(dd, 1);
140 bCof1 = Cudd_bddIthVar(dd, 2);
141 pNode->
pData = Cudd_bddIte( dd, bSpin, bCof1, bCof0 ); Cudd_Ref( (DdNode *)pNode->
pData );
158 DdManager * dd = (DdManager *)pNtkNew->
pManFunc;
160 DdNode * bSpin, * bCof0, * bCof1;
161 pNode = Abc_NtkCreateNode( pNtkNew );
168 bSpin = Cudd_bddIthVar(dd, 1);
169 bCof0 = Cudd_bddIte( dd, bSpin, Cudd_bddIthVar(dd, 3), Cudd_bddIthVar(dd, 2) ); Cudd_Ref( bCof0 );
170 bCof1 = Cudd_bddIte( dd, bSpin, Cudd_bddIthVar(dd, 5), Cudd_bddIthVar(dd, 4) ); Cudd_Ref( bCof1 );
171 bSpin = Cudd_bddIthVar(dd, 0);
172 pNode->
pData = Cudd_bddIte( dd, bSpin, bCof1, bCof0 ); Cudd_Ref( (DdNode *)pNode->
pData );
173 Cudd_RecursiveDeref( dd, bCof0 );
174 Cudd_RecursiveDeref( dd, bCof1 );
191 DdManager * dd = (DdManager *)pNtkNew->
pManFunc;
193 DdNode * bSpin, * bCof0, * bCof1;
195 pNodeBot = Abc_NtkCreateNode( pNtkNew );
200 bSpin = Cudd_bddIthVar(dd, 0);
201 bCof0 = Cudd_bddIte( dd, Cudd_bddIthVar(dd, 1), Cudd_bddIthVar(dd, 3), Cudd_bddIthVar(dd, 2) ); Cudd_Ref( bCof0 );
202 bCof1 = Cudd_bddIthVar(dd, 1);
203 pNodeBot->
pData = Cudd_bddIte( dd, bSpin, bCof1, bCof0 ); Cudd_Ref( (DdNode *)pNodeBot->
pData );
204 Cudd_RecursiveDeref( dd, bCof0 );
206 pNodeTop = Abc_NtkCreateNode( pNtkNew );
211 bSpin = Cudd_bddIthVar(dd, 0);
212 bCof0 = Cudd_bddIthVar(dd, 1);
213 bCof1 = Cudd_bddIte( dd, Cudd_bddIthVar(dd, 1), Cudd_bddIthVar(dd, 3), Cudd_bddIthVar(dd, 2) ); Cudd_Ref( bCof1 );
214 pNodeTop->
pData = Cudd_bddIte( dd, bSpin, bCof1, bCof0 ); Cudd_Ref( (DdNode *)pNodeTop->
pData );
215 Cudd_RecursiveDeref( dd, bCof1 );
232 DdManager * dd = (DdManager *)pNtkNew->
pManFunc;
234 DdNode * bSpin, * bCof0, * bCof1;
236 pNodeBot = Abc_NtkCreateNode( pNtkNew );
240 bSpin = Cudd_bddIthVar(dd, 0);
241 bCof0 = Cudd_bddIthVar(dd, 1);
242 bCof1 = Cudd_bddIthVar(dd, 2);
243 pNodeBot->
pData = Cudd_bddIte( dd, bSpin, bCof1, bCof0 ); Cudd_Ref( (DdNode *)pNodeBot->
pData );
245 pNodeTop = Abc_NtkCreateNode( pNtkNew );
251 bSpin = Cudd_bddIthVar(dd, 0);
252 bCof0 = Cudd_bddIthVar(dd, 2);
253 bCof1 = Cudd_bddIte( dd, Cudd_bddIthVar(dd, 1), Cudd_bddIthVar(dd, 4), Cudd_bddIthVar(dd, 3) ); Cudd_Ref( bCof1 );
254 pNodeTop->
pData = Cudd_bddIte( dd, bSpin, bCof1, bCof0 ); Cudd_Ref( (DdNode *)pNodeTop->
pData );
255 Cudd_RecursiveDeref( dd, bCof1 );
272 Abc_Obj_t * pNodesBot[3], * pNodesTop[3];
274 pNodesBot[0] = pFanins[1];
275 pNodesBot[1] = pFanins[2];
276 pNodesBot[2] = pFanins[3];
277 pNodesTop[1] = Abc_NtkBddMux21( pNtkNew, pNodesBot );
279 pNodesBot[0] = pFanins[1];
280 pNodesBot[1] = pFanins[4];
281 pNodesBot[2] = pFanins[5];
282 pNodesTop[2] = Abc_NtkBddMux21( pNtkNew, pNodesBot );
284 pNodesTop[0] = pFanins[0];
285 return Abc_NtkBddMux21( pNtkNew, pNodesTop );
299DdNode * Abc_NtkBddCofactors_rec( DdManager * dd, DdNode * bNode,
int iCof,
int iLevel,
int nLevels )
301 DdNode * bNode0, * bNode1;
302 if ( Cudd_IsConstant(bNode) || iLevel == nLevels )
304 if ( Cudd_ReadPerm( dd, Cudd_NodeReadIndex(bNode) ) > iLevel )
309 else if ( Cudd_IsComplement(bNode) )
311 bNode0 = Cudd_Not(cuddE(Cudd_Regular(bNode)));
312 bNode1 = Cudd_Not(cuddT(Cudd_Regular(bNode)));
316 bNode0 = cuddE(bNode);
317 bNode1 = cuddT(bNode);
319 if ( (iCof >> (nLevels-1-iLevel)) & 1 )
320 return Abc_NtkBddCofactors_rec( dd, bNode1, iCof, iLevel + 1, nLevels );
321 return Abc_NtkBddCofactors_rec( dd, bNode0, iCof, iLevel + 1, nLevels );
335Vec_Ptr_t * Abc_NtkBddCofactors( DdManager * dd, DdNode * bNode,
int Level )
338 int i, nCofs = (1<<Level);
339 assert( Level > 0 && Level < 10 );
340 vCofs = Vec_PtrAlloc( 8 );
341 for ( i = 0; i < nCofs; i++ )
342 Vec_PtrPush( vCofs, Abc_NtkBddCofactors_rec( dd, bNode, i, 0, Level ) );
357static int Vec_PtrSortCompare(
void ** pp1,
void ** pp2 )
383 assert( Abc_ObjFaninNum(pNode) > Level );
385 pNodeNew = Abc_NtkCreateNode( pNtkNew );
387 for ( i = Level; i < Abc_ObjFaninNum(pNode); i++ )
396 bFuncNew =
Extra_bddMove( dd, bCof, -Level ); Cudd_Ref( bFuncNew );
407 Cudd_RecursiveDeref( dd, bFuncNew );
425 DdManager * ddNew = (DdManager *)pNtkNew->
pManFunc;
426 DdNode * bCof, * bUniq, * bMint, * bTemp, * bFunc, * bBits[10], ** pbCodeVars;
427 Abc_Obj_t * pNodeNew = NULL, * pNodeBS[10];
428 int nLutSize = Abc_Base2Log( Vec_PtrSize(vCofs) );
429 int nBits = Abc_Base2Log( Vec_PtrSize(vUniq) );
431 assert( nBits + 2 <= nLutSize );
432 assert( nLutSize < Abc_ObjFaninNum(pNode) );
434 for ( b = 0; b < nBits; b++ )
435 bBits[b] = Cudd_ReadLogicZero(ddNew), Cudd_Ref( bBits[b] );
442 assert( u < Vec_PtrSize(vUniq) );
443 for ( b = 0; b < nBits; b++ )
445 if ( ((u >> b) & 1) == 0 )
448 bBits[b] = Cudd_bddOr( ddNew, bTemp = bBits[b], bMint ); Cudd_Ref( bBits[b] );
449 Cudd_RecursiveDeref( ddNew, bTemp );
450 Cudd_RecursiveDeref( ddNew, bMint );
454 for ( b = 0; b < nBits; b++ )
456 pNodeBS[b] = Abc_NtkCreateNode( pNtkNew );
457 for ( i = 0; i < nLutSize; i++ )
459 pNodeBS[b]->pData = bBits[b];
462 pNodeNew = Abc_NtkCreateNode( pNtkNew );
464 for ( i = nLutSize; i < Abc_ObjFaninNum(pNode); i++ )
467 for ( b = 0; b < nBits; b++ )
470 bFunc = Cudd_ReadLogicZero(ddNew); Cudd_Ref( bFunc );
471 pbCodeVars = ddNew->vars + Abc_ObjFaninNum(pNode) - nLutSize;
474 bUniq =
Extra_bddMove( ddOld, bUniq, -nLutSize ); Cudd_Ref( bUniq );
476 Cudd_RecursiveDeref( ddOld, bTemp );
479 bMint = Cudd_bddAnd( ddNew, bTemp = bMint, bUniq ); Cudd_Ref( bMint );
480 Cudd_RecursiveDeref( ddNew, bTemp );
481 Cudd_RecursiveDeref( ddNew, bUniq );
483 bFunc = Cudd_bddOr( ddNew, bTemp = bFunc, bMint ); Cudd_Ref( bFunc );
484 Cudd_RecursiveDeref( ddNew, bTemp );
485 Cudd_RecursiveDeref( ddNew, bMint );
487 pNodeNew->
pData = bFunc;
506 DdManager * ddNew = (DdManager *)pNtkNew->
pManFunc;
507 DdNode * bCof0 = NULL, * bCof1 = NULL, * bSupp, * bTemp, * bVar;
508 DdNode * bCof0n, * bCof1n;
509 int i, iCof, iFreeVar, fCof1Smaller = -1;
510 assert( Abc_ObjFaninNum(pNode) == nLutSize + 1 );
511 for ( iCof = 0; iCof < Abc_ObjFaninNum(pNode); iCof++ )
513 bVar = Cudd_bddIthVar( ddOld, iCof );
514 bCof0 = Cudd_Cofactor( ddOld, (DdNode *)pNode->
pData, Cudd_Not(bVar) ); Cudd_Ref( bCof0 );
515 bCof1 = Cudd_Cofactor( ddOld, (DdNode *)pNode->
pData, bVar ); Cudd_Ref( bCof1 );
516 if ( Cudd_SupportSize( ddOld, bCof0 ) <= nLutSize - 2 )
521 if ( Cudd_SupportSize( ddOld, bCof1 ) <= nLutSize - 2 )
526 Cudd_RecursiveDeref( ddOld, bCof0 );
527 Cudd_RecursiveDeref( ddOld, bCof1 );
529 if ( iCof == Abc_ObjFaninNum(pNode) )
532 bSupp = Cudd_Support( ddOld, fCof1Smaller? bCof1 : bCof0 ); Cudd_Ref( bSupp );
534 for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
536 assert( i == Cudd_ReadPerm(ddOld, i) );
539 for ( bTemp = bSupp; !Cudd_IsConstant(bTemp); bTemp = cuddT(bTemp) )
540 if ( i == (
int)Cudd_NodeReadIndex(bTemp) )
542 if ( Cudd_IsConstant(bTemp) )
548 assert( iFreeVar != iCof && iFreeVar < Abc_ObjFaninNum(pNode) );
549 Cudd_RecursiveDeref( ddOld, bSupp );
553 Cudd_RecursiveDeref( ddOld, bCof0 );
554 Cudd_RecursiveDeref( ddOld, bCof1 );
556 pNodeBot = Abc_NtkCreateNode( pNtkNew );
557 for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
559 pNodeBot->
pData = fCof1Smaller? bCof0n : bCof1n;
561 pNodeTop = Abc_NtkCreateNode( pNtkNew );
562 for ( i = 0; i < Abc_ObjFaninNum(pNode); i++ )
568 pNodeTop->
pData = Cudd_bddIte( ddNew,
569 Cudd_bddIthVar(ddNew, iCof),
570 fCof1Smaller? bCof1n : Cudd_bddIthVar(ddNew, iFreeVar),
571 fCof1Smaller? Cudd_bddIthVar(ddNew, iFreeVar) : bCof0n );
572 Cudd_Ref( (DdNode *)pNodeTop->
pData );
573 Cudd_RecursiveDeref( ddNew, fCof1Smaller? bCof1n : bCof0n );
589int Abc_NtkBddNodeCompareByLevel( DdNode ** pp1, DdNode ** pp2 )
591 return (*pp1)->
Id - (*pp2)->Id;
593Vec_Ptr_t * Abc_NtkBddCollectByLevel( DdManager * dd, DdNode * aFunc )
595 DdGen *gen; DdNode *node;
int i;
596 Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
597 Cudd_ForeachNode( dd, aFunc, gen, node )
598 Vec_PtrPush( vNodes, node ), node->Id = Cudd_ReadPerm( dd, (
int)node->index );
599 Vec_PtrSort( vNodes, (
int (*)(
const void *,
const void *))Abc_NtkBddNodeCompareByLevel );
604void Abc_NtkBddCollectPrint3( DdManager * dd, DdNode * aFunc )
606 Vec_Ptr_t * vNodes = Abc_NtkBddCollectByLevel( dd, aFunc );
607 Vec_PtrPrintPointers( vNodes );
608 Vec_PtrFree( vNodes );
623Vec_Ptr_t * Abc_NtkBddFetchNodes( DdManager * dd, DdNode * aFunc )
625 Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
626 DdGen *gen; DdNode *node;
627 Cudd_ForeachNode( dd, aFunc, gen, node)
628 Vec_PtrPush(vNodes, node), node->Id = 0;
631void Abc_NtkBddCleanNodes( DdManager * dd, DdNode * aFunc )
633 DdGen *gen; DdNode *node;
634 Cudd_ForeachNode( dd, aFunc, gen, node)
637void Abc_NtkBddCollectPtr_rec( DdManager * dd, DdNode * aFunc,
Vec_Ptr_t * vNodes )
641 if ( !cuddIsConstant(aFunc) ) {
642 Abc_NtkBddCollectPtr_rec( dd, cuddE(aFunc), vNodes );
643 Abc_NtkBddCollectPtr_rec( dd, cuddT(aFunc), vNodes );
645 aFunc->Id = Vec_PtrSize(vNodes) + 1;
646 Vec_PtrPush(vNodes, aFunc);
648Vec_Ptr_t * Abc_NtkBddCollectPtr( DdManager * dd, DdNode * aFunc )
650 Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
651 Abc_NtkBddCleanNodes( dd, aFunc );
652 Abc_NtkBddCollectPtr_rec( dd, aFunc, vNodes );
655void Abc_NtkBddCollectPrint2( DdManager * dd, DdNode * aFunc )
657 Vec_Ptr_t * vNodes = Abc_NtkBddCollectPtr( dd, aFunc );
658 Vec_PtrPrintPointers( vNodes );
659 Vec_PtrFree( vNodes );
674static inline word Abc_Bdd2Word( DdNode * f ) {
union { DdNode * f;
word w; } v; v.f = f;
return v.w; }
675static inline DdNode * Abc_Word2Bdd(
word w ) {
union { DdNode * f;
word w; } v; v.w = w;
return v.f; }
677static inline int Abc_Bdd2Int( DdNode * F, DdNode * f ) {
return (
int)(Abc_Bdd2Word(F) ^ Abc_Bdd2Word(f)) >> 3; }
678static inline DdNode * Abc_Int2Bdd( DdNode * F,
int diff ) {
return Abc_Word2Bdd(Abc_Bdd2Word(F) ^ (
word)(diff << 3)); }
680static inline int Abc_BddIndex( DdManager * dd, DdNode * f ) {
return cuddIsConstant(f) ? dd->size : (int)f->index; }
681static inline int Abc_BddLevel( DdManager * dd, DdNode * f ) {
return cuddIsConstant(f) ? dd->size : Cudd_ReadPerm(dd, (
int)f->index); }
683void Abc_NtkBddCollectInt_rec( DdManager * dd, DdNode * aRef, DdNode * aFunc,
Vec_Wec_t * vNodes )
685 if ( Cudd_IsComplement(aFunc->next) )
687 aFunc->next = Cudd_Not(aFunc->next);
688 if ( !cuddIsConstant(aFunc) ) {
689 Abc_NtkBddCollectInt_rec( dd, aRef, cuddE(aFunc), vNodes );
690 Abc_NtkBddCollectInt_rec( dd, aRef, cuddT(aFunc), vNodes );
693 Vec_WecPush( vNodes, Abc_BddLevel(dd, aFunc), Abc_Bdd2Int(aRef, aFunc) );
695Vec_Wec_t * Abc_NtkBddCollectInt( DdManager * dd, DdNode * aFunc )
697 Vec_Wec_t * vNodes = Vec_WecStart( dd->size+1 );
698 Abc_NtkBddCollectInt_rec( dd, aFunc, aFunc, vNodes );
703void Abc_NtkBddCollectPrint( DdManager * dd, DdNode * aFunc )
705 Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
706 Vec_WecPrint( vNodes, 0 );
707 Vec_WecFree( vNodes );
721Vec_Int_t * Abc_NtkBddCollectHighest( DdManager * dd, DdNode * aFunc,
Vec_Wec_t * vNodes )
723 Vec_Int_t * vRes = Vec_IntStartFull( Vec_WecMaxEntry(vNodes)+1 );
724 Vec_Int_t * vLevel;
int i, k, Obj, * pEntry;
727 DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
728 pEntry = Vec_IntEntryP( vRes, Abc_Bdd2Int(aFunc, cuddE(aNode)) );
729 if ( *pEntry == -1 ) *pEntry = i;
730 pEntry = Vec_IntEntryP( vRes, Abc_Bdd2Int(aFunc, cuddT(aNode)) );
731 if ( *pEntry == -1 ) *pEntry = i;
735void Abc_NtkBddCollectProfile( DdManager * dd, DdNode * aFunc,
Vec_Wec_t * vNodes,
int * pProf )
737 memset( pProf, 0,
sizeof(
int)*(dd->size+1) );
738 Vec_Int_t * vHighest = Abc_NtkBddCollectHighest( dd, aFunc, vNodes );
743 int lev, Start = Vec_IntEntry( vHighest, Obj );
744 for ( lev = Start+1; lev <= i; lev++ )
747 printf(
" Size = %5d ", Vec_IntSize(vHighest) );
748 Vec_IntFree( vHighest );
750void Abc_NtkBddTestProfile( DdManager * dd, DdNode * aFunc )
752 Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
753 int i, Total = 0, Profile[100];
assert( dd->size < 100 );
754 Abc_NtkBddCollectProfile( dd, aFunc, vNodes, Profile );
756 for ( i = 0; i <= dd->size; i++ )
757 printf(
"%3d", Profile[i] ), Total += Profile[i];
758 printf(
" Total = %d\n", Total );
759 Vec_WecFree( vNodes );
761Vec_Wec_t * Abc_NtkBddCollectCofs( DdManager * dd, DdNode * aFunc,
Vec_Wec_t * vNodes )
763 Vec_Wec_t * vCofs = Vec_WecStart( dd->size+1 );
764 Vec_Int_t * vHighest = Abc_NtkBddCollectHighest( dd, aFunc, vNodes );
766 Vec_WecPush( vCofs, 0, 0 );
769 int lev, Start = Vec_IntEntry( vHighest, Obj );
770 for ( lev = Start+1; lev <= i; lev++ )
771 Vec_WecPush( vCofs, lev, Obj );
773 Vec_IntFree( vHighest );
776Vec_Wec_t * Abc_NtkBddCollecInfo1( DdManager * dd, DdNode * aFunc )
778 Vec_Wec_t * vInfo = Vec_WecStart( dd->size );
779 Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
780 Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( dd, aFunc, vNodes );
782 for (
int a = 0; a < dd->size; a++ ) {
784 for (
int n = 0; n < 2; n++ ) {
788 Abc_Int2Bdd(aFunc, Obj)->Id = 0;
793 Vec_IntPush( Vec_WecEntry(vInfo, a), 1 );
796 DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
797 if ( aNode->Id == 0 )
799 if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 0 )
800 cuddE(aNode)->Id |= 1;
801 if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 1 )
802 cuddT(aNode)->Id |= 1;
804 Vec_Int_t * vCof = Vec_WecEntry(vCofs, i+1);
807 Counter += (int)Abc_Int2Bdd(aFunc, Obj)->Id;
809 Vec_IntPush( Vec_WecEntry(vInfo, a), Counter );
811 int * pEntry = Vec_IntEntryP( Vec_WecEntry(vInfo, a), i+1 );
812 *pEntry = Abc_MaxInt( *pEntry, Counter );
819 Vec_WecFree( vCofs );
820 Vec_WecFree( vNodes );
823Vec_Wec_t * Abc_NtkBddCollecInfo2( DdManager * dd, DdNode * aFunc )
825 Vec_Wec_t * vInfo = Vec_WecStart( dd->size*(dd->size-1)/2 );
826 Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
827 Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( dd, aFunc, vNodes );
828 Vec_Int_t * vLevel;
int i, k, Obj, c = 0;
829 for (
int a = 0; a < dd->size; a++ )
830 for (
int b = a+1; b < dd->size; b++ ) {
831 Vec_Int_t * vInfo1 = Vec_WecEntry(vInfo, c++);
833 for (
int n = 0; n < 4; n++ ) {
834 word Value = ((
word)(n & 1) << a) | ((
word)((n >> 1) & 1) << b);
837 Abc_Int2Bdd(aFunc, Obj)->Id = 0;
840 Vec_IntPush( vInfo1, 1 );
843 DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
844 if ( aNode->Id == 0 )
846 if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 0 )
847 cuddE(aNode)->Id |= 1;
848 if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 1 )
849 cuddT(aNode)->Id |= 1;
851 Vec_Int_t * vCof = Vec_WecEntry(vCofs, i+1);
854 Counter += (int)Abc_Int2Bdd(aFunc, Obj)->Id;
856 Vec_IntPush( vInfo1, Counter );
858 int * pEntry = Vec_IntEntryP( vInfo1, i+1 );
859 *pEntry = Abc_MaxInt( *pEntry, Counter );
864 assert( c == Vec_WecSize(vInfo) );
865 Vec_WecFree( vCofs );
866 Vec_WecFree( vNodes );
869Vec_Wec_t * Abc_NtkBddCollecInfo3( DdManager * dd, DdNode * aFunc )
871 Vec_Wec_t * vInfo = Vec_WecStart( dd->size*(dd->size-1)*(dd->size-2)/6 );
872 Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
873 Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( dd, aFunc, vNodes );
874 Vec_Int_t * vLevel;
int i, k, Obj, d = 0;
875 for (
int a = 0; a < dd->size; a++ )
876 for (
int b = a+1; b < dd->size; b++ )
877 for (
int c = b+1; c < dd->size; c++ ) {
878 Vec_Int_t * vInfo1 = Vec_WecEntry(vInfo, d++);
880 for (
int n = 0; n < 8; n++ ) {
881 word Value = ((
word)(n & 1) << a) | ((
word)((n >> 1) & 1) << b) | ((
word)((n >> 2) & 1) << c);
884 Abc_Int2Bdd(aFunc, Obj)->Id = 0;
887 Vec_IntPush( vInfo1, 1 );
890 DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
891 if ( aNode->Id == 0 )
893 if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 0 )
894 cuddE(aNode)->Id |= 1;
895 if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 1 )
896 cuddT(aNode)->Id |= 1;
898 Vec_Int_t * vCof = Vec_WecEntry(vCofs, i+1);
901 Counter += (int)Abc_Int2Bdd(aFunc, Obj)->Id;
903 Vec_IntPush( vInfo1, Counter );
905 int * pEntry = Vec_IntEntryP( vInfo1, i+1 );
906 *pEntry = Abc_MaxInt( *pEntry, Counter );
911 assert( d == Vec_WecSize(vInfo) );
912 Vec_WecFree( vCofs );
913 Vec_WecFree( vNodes );
919 printf(
"Cofactor counts:\n" );
926 printf(
" %2d", Vec_IntSize(vLevel) );
929 printf(
"%2d %c : ", i,
'a'+i );
934 printf(
" %2d", Obj );
941 printf(
"Cofactor counts:\n" );
948 printf(
" %2d", Vec_IntSize(vLevel) );
950 int c = 0, Limit = Vec_IntSize(Vec_WecEntry(vInfo, 0))-1;
951 for (
int a = 0; a < Limit; a++ )
952 for (
int b = a+1; b < Limit; b++ ) {
953 Vec_Int_t * vLevel = Vec_WecEntry(vInfo, c++);
954 printf(
" %c%c : ",
'a'+a,
'a'+b );
955 int Limit = Abc_MaxInt(a,b);
960 printf(
" %2d", Obj );
963 assert( c == Vec_WecSize(vInfo) );
968 printf(
"Cofactor counts:\n" );
975 printf(
" %2d", Vec_IntSize(vLevel) );
977 int d = 0, Limit = Vec_IntSize(Vec_WecEntry(vInfo, 0))-1;
978 for (
int a = 0; a < Limit; a++ )
979 for (
int b = a+1; b < Limit; b++ )
980 for (
int c = b+1; c < Limit; c++ ) {
981 Vec_Int_t * vLevel = Vec_WecEntry(vInfo, d++);
982 printf(
" %c%c%c : ",
'a'+a,
'a'+b,
'a'+c );
983 int Limit = Abc_MaxInt(a,Abc_MaxInt(b,c));
988 printf(
" %2d", Obj );
991 assert( d == Vec_WecSize(vInfo) );
994void Abc_NtkBddDecExploreOne( DdManager * dd, DdNode * bFunc,
int iOrder )
996 DdManager * ddNew = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
997 int i, * pProfile =
ABC_CALLOC(
int, dd->size + 100 );
998 Cudd_AutodynEnable( ddNew, CUDD_REORDER_SYMM_SIFT );
999 Vec_Int_t * vPerm = Vec_IntStartNatural( dd->size );
if ( iOrder ) Vec_IntRandomizeOrder( vPerm );
1000 Vec_Int_t * vPermInv = Vec_IntInvert( vPerm, -1 );
1001 DdNode * bFuncNew =
Extra_TransferPermute( dd, ddNew, bFunc, Vec_IntArray(vPerm) ); Cudd_Ref(bFuncNew);
1002 if ( iOrder ) Cudd_ReduceHeap( ddNew, CUDD_REORDER_SYMM_SIFT, 1 );
1003 Vec_IntFree( vPerm );
1004 DdNode * aFuncNew = Cudd_BddToAdd( ddNew, bFuncNew ); Cudd_Ref( aFuncNew );
1007 printf(
"Random order %2d: ", iOrder );
1009 printf(
"Natural order: " );
1010 printf(
"BDD size = %3d ", Cudd_DagSize(aFuncNew) );
1011 for ( i = 0; i < dd->size; i++ )
1012 printf(
" %c",
'a' + Vec_IntEntry(vPermInv, ddNew->invperm[i]) );
1016 Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( ddNew, aFuncNew );
1017 printf(
"Nodes by level:\n" );
1018 Vec_WecPrint( vNodes, 0 );
1019 Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( ddNew, aFuncNew, vNodes );
1020 printf(
"Cofactors by level:\n" );
1021 Vec_WecPrint( vCofs, 0 );
1022 Vec_Wec_t * vInfo1 = Abc_NtkBddCollecInfo1( ddNew, aFuncNew );
1023 Abc_NtkBddPrintInfo1( vInfo1, vCofs );
1024 Vec_Wec_t * vInfo2 = Abc_NtkBddCollecInfo2( ddNew, aFuncNew );
1025 Abc_NtkBddPrintInfo2( vInfo2, vCofs );
1026 Vec_Wec_t * vInfo3 = Abc_NtkBddCollecInfo3( ddNew, aFuncNew );
1027 Abc_NtkBddPrintInfo3( vInfo3, vCofs );
1029 Vec_WecFree( vNodes );
1030 Vec_WecFree( vCofs );
1031 Vec_WecFree( vInfo1 );
1032 Vec_WecFree( vInfo2 );
1033 Vec_WecFree( vInfo3 );
1035 Cudd_RecursiveDeref( ddNew, aFuncNew );
1036 Cudd_RecursiveDeref( ddNew, bFuncNew );
1043 DdNode * bFunc = (DdNode *)pNode->
pData;
1045 if ( Abc_ObjIsNode(pNode) )
1046 for ( i = 0; i < 4; i++ )
1047 Abc_NtkBddDecExploreOne( dd, bFunc, i );
1069 assert( Abc_ObjFaninNum(pNode) > nLutSize );
1071 if ( Abc_ObjFaninNum(pNode) == nLutSize + 1 )
1074 pNodeNew = Abc_NtkBddFindCofactor( pNtkNew, pNode, nLutSize );
1075 if ( pNodeNew != NULL )
1078 printf(
"Decomposing %d-input node %d using MUX.\n",
1079 Abc_ObjFaninNum(pNode), Abc_ObjId(pNode) );
1085 vCofs = Abc_NtkBddCofactors( dd, (DdNode *)pNode->
pData, nLutSize );
1086 vUniq = Vec_PtrDup( vCofs );
1087 Vec_PtrUniqify( vUniq, (
int (*)(
const void *,
const void *))Vec_PtrSortCompare );
1089 if( Vec_PtrSize(vUniq) > (1 << (nLutSize-2)) )
1091 Vec_PtrFree( vCofs );
1092 vCofs = Abc_NtkBddCofactors( dd, (DdNode *)pNode->
pData, 2 );
1094 printf(
"Decomposing %d-input node %d using cofactoring with %d cofactors (myu = %d).\n",
1095 Abc_ObjFaninNum(pNode), Abc_ObjId(pNode), Vec_PtrSize(vCofs), Vec_PtrSize(vUniq) );
1097 pCofs[0] = Abc_ObjFanin(pNode, 0)->
pCopy;
1098 pCofs[1] = Abc_ObjFanin(pNode, 1)->
pCopy;
1100 pCofs[2+i] = Abc_NtkCreateCofLut( pNtkNew, dd, bCof, pNode, 2 );
1101 if ( nLutSize == 4 )
1102 pNodeNew = Abc_NtkBddMux412( pNtkNew, pCofs );
1103 else if ( nLutSize == 5 )
1104 pNodeNew = Abc_NtkBddMux412a( pNtkNew, pCofs );
1105 else if ( nLutSize == 6 )
1106 pNodeNew = Abc_NtkBddMux411( pNtkNew, pCofs );
1113 printf(
"Decomposing %d-input node %d using Curtis with %d unique columns.\n",
1114 Abc_ObjFaninNum(pNode), Abc_ObjId(pNode), Vec_PtrSize(vUniq) );
1115 pNodeNew = Abc_NtkBddCurtis( pNtkNew, pNode, vCofs, vUniq );
1117 Vec_PtrFree( vCofs );
1118 Vec_PtrFree( vUniq );
1133void Abc_NtkLutminConstruct(
Abc_Ntk_t * pNtkClp,
Abc_Ntk_t * pNtkDec,
int nLutSize,
int fVerbose )
1141 if ( Abc_ObjFaninNum(pNode) <= nLutSize )
1148 pNode->
pCopy = Abc_NtkBddDecompose( pNtkDec, pNode, nLutSize, fVerbose );
1150 Vec_PtrFree( vNodes );
1164Abc_Ntk_t * Abc_NtkLutminInt(
Abc_Ntk_t * pNtk,
int nLutSize,
int fReorder,
int fVerbose )
1176 Abc_NtkLutminConstruct( pNtk, pNtkDec, nLutSize, fVerbose );
1202 printf(
"The LUT count (%d) should be at least 4.\n", nLutSize );
1207 printf(
"The LUT count (%d) should not exceed 6.\n", nLutSize );
1211 if ( Abc_NtkIsStrash(pNtkInit) )
1216 pNtkNew =
Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, fReorder, 0, 0, 0 );
1218 if ( pNtkNew == NULL )
1221 if ( !Abc_NtkIsBddLogic(pNtkNew) )
1227 printf(
"*** Iteration %d:\n", i+1 );
1229 printf(
"Decomposing network with %d nodes and %d max fanin count for K = %d.\n",
1231 pNtkNew = Abc_NtkLutminInt( pTemp = pNtkNew, nLutSize, fReorder, fVerbose );
1241 printf(
"Abc_NtkLutmin: The network check has failed.\n" );
void Abc_NtkBddReorder(Abc_Ntk_t *pNtk, int fVerbose)
DECLARATIONS ///.
ABC_NAMESPACE_IMPL_START Abc_Ntk_t * Abc_NtkLutmin(Abc_Ntk_t *pNtkInit, int nLutSize, int fReorder, int fVerbose)
DECLARATIONS ///.
void Abc_NtkBddDecExplore(Abc_Obj_t *pNode)
int Abc_NtkFraigSweep(Abc_Ntk_t *pNtk, int fUseInv, int fExdc, int fVerbose, int fVeryVerbose)
FUNCTION DEFINITIONS ///.
struct Abc_Obj_t_ Abc_Obj_t
ABC_DLL int Abc_NtkGetFaninMax(Abc_Ntk_t *pNtk)
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
ABC_DLL Abc_Obj_t * Abc_NtkDupObj(Abc_Ntk_t *pNtkNew, Abc_Obj_t *pObj, int fCopyName)
ABC_DLL Vec_Ptr_t * Abc_NtkDfs(Abc_Ntk_t *pNtk, int fCollectAll)
ABC_DLL int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
#define Abc_ObjForEachFanin(pObj, pFanin, i)
ABC_DLL int Abc_NtkToBdd(Abc_Ntk_t *pNtk)
ABC_DLL Abc_Ntk_t * Abc_NtkCollapse(Abc_Ntk_t *pNtk, int fBddSizeMax, int fDualRail, int fReorder, int fReverse, int fDumpOrder, int fVerbose)
DECLARATIONS ///.
struct Abc_Ntk_t_ Abc_Ntk_t
ABC_DLL void Abc_NtkFinalize(Abc_Ntk_t *pNtk, Abc_Ntk_t *pNtkNew)
ABC_DLL int Abc_NtkLogicMakeSimpleCos(Abc_Ntk_t *pNtk, int fDuplicate)
ABC_DLL Abc_Ntk_t * Abc_NtkStrash(Abc_Ntk_t *pNtk, int fAllNodes, int fCleanup, int fRecord)
ABC_DLL int Abc_NtkMinimumBase(Abc_Ntk_t *pNtk)
DECLARATIONS ///.
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
ABC_DLL Abc_Ntk_t * Abc_NtkStartFrom(Abc_Ntk_t *pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func)
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
#define Abc_NtkForEachNode(pNtk, pNode, i)
unsigned Abc_Random(int fReset)
#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 ///.
unsigned __int64 word
DECLARATIONS ///.
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
#define Vec_WecForEachLevelStart(vGlob, vVec, i, LevelStart)
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
#define Vec_WecForEachLevelStop(vGlob, vVec, i, LevelStop)