#include "abc.h"
#include "dec.h"
#include "dsd.h"
#include "cut.h"
Go to the source code of this file.
#define RST_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand())) |
CFile****************************************************************
FileName [abcRestruct.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [
] DECLARATIONS ///
Definition at line 30 of file abcRestruct.c.
typedef struct Abc_ManRst_t_ Abc_ManRst_t |
Definition at line 32 of file abcRestruct.c.
int Abc_Abc_NodeResubCollectDivs | ( | Abc_ManRst_t * | p, | |
Abc_Obj_t * | pRoot, | |||
Cut_Cut_t * | pCut | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 1095 of file abcRestruct.c.
01096 { 01097 Abc_Obj_t * pNode, * pFanout; 01098 int i, k; 01099 // collect the leaves of the cut 01100 Vec_PtrClear( p->vDecs ); 01101 Abc_NtkIncrementTravId( pRoot->pNtk ); 01102 for ( i = 0; i < (int)pCut->nLeaves; i++ ) 01103 { 01104 pNode = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]); 01105 if ( pNode == NULL ) // the so-called "bad cut phenomenon" is due to removed nodes 01106 return 0; 01107 Vec_PtrPush( p->vDecs, pNode ); 01108 Abc_NodeSetTravIdCurrent( pNode ); 01109 } 01110 // explore the fanouts 01111 Vec_PtrForEachEntry( p->vDecs, pNode, i ) 01112 { 01113 // if the fanout has both fanins in the set, add it 01114 Abc_ObjForEachFanout( pNode, pFanout, k ) 01115 { 01116 if ( Abc_NodeIsTravIdCurrent(pFanout) || Abc_ObjIsPo(pFanout) ) 01117 continue; 01118 if ( Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pFanout)) && Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pFanout)) ) 01119 { 01120 Vec_PtrPush( p->vDecs, pFanout ); 01121 Abc_NodeSetTravIdCurrent( pFanout ); 01122 } 01123 } 01124 } 01125 return 1; 01126 }
int Abc_NodeCheckFull | ( | Abc_ManRst_t * | p, | |
Dec_Graph_t * | pGraph | |||
) |
Function*************************************************************
Synopsis [Full equality check.]
Description []
SideEffects []
SeeAlso []
Definition at line 1233 of file abcRestruct.c.
void Abc_NodeEdgeDsdPermute | ( | Dec_Graph_t * | pGraph, | |
Abc_ManRst_t * | pManRst, | |||
Vec_Int_t * | vEdges, | |||
int | fExor | |||
) |
Function*************************************************************
Synopsis [Moves closer to the end the node that is best for sharing.]
Description [If the flag is set, tries to find an EXOR, otherwise, tries to find an OR.]
SideEffects []
SeeAlso []
Definition at line 482 of file abcRestruct.c.
00483 { 00484 Dec_Edge_t eNode1, eNode2, eNode3; 00485 Abc_Obj_t * pNode1, * pNode2, * pNode3, * pTemp; 00486 int LeftBound = 0, RightBound, i; 00487 // get the right bound 00488 RightBound = Vec_IntSize(vEdges) - 2; 00489 assert( LeftBound <= RightBound ); 00490 if ( LeftBound == RightBound ) 00491 return; 00492 // get the two last nodes 00493 eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound + 1) ); 00494 eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound ) ); 00495 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc; 00496 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc; 00497 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl ); 00498 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl ); 00499 // quit if the last node does not exist 00500 if ( pNode1 == NULL ) 00501 return; 00502 // find the first node that can be shared 00503 for ( i = RightBound; i >= LeftBound; i-- ) 00504 { 00505 // get the third node 00506 eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, i) ); 00507 pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc; 00508 pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl ); 00509 if ( pNode3 == NULL ) 00510 continue; 00511 // check if the node exists 00512 if ( fExor ) 00513 { 00514 if ( pNode1 && pNode3 ) 00515 { 00516 pTemp = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode3, NULL ); 00517 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00518 continue; 00519 00520 if ( pNode3 == pNode2 ) 00521 return; 00522 Vec_IntWriteEntry( vEdges, i, Dec_EdgeToInt(eNode2) ); 00523 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) ); 00524 return; 00525 } 00526 } 00527 else 00528 { 00529 if ( pNode1 && pNode3 ) 00530 { 00531 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) ); 00532 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00533 continue; 00534 00535 if ( eNode3.Node == eNode2.Node ) 00536 return; 00537 Vec_IntWriteEntry( vEdges, i, Dec_EdgeToInt(eNode2) ); 00538 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) ); 00539 return; 00540 } 00541 } 00542 } 00543 }
void Abc_NodeEdgeDsdPushOrdered | ( | Dec_Graph_t * | pGraph, | |
Vec_Int_t * | vEdges, | |||
int | Edge | |||
) |
Function*************************************************************
Synopsis [Adds the new edge in the given order.]
Description [Similar to Vec_IntPushOrder, except in decreasing order.]
SideEffects []
SeeAlso []
Definition at line 556 of file abcRestruct.c.
00557 { 00558 int i, NodeOld, NodeNew; 00559 vEdges->nSize++; 00560 for ( i = vEdges->nSize-2; i >= 0; i-- ) 00561 { 00562 NodeOld = Dec_IntToEdge(vEdges->pArray[i]).Node; 00563 NodeNew = Dec_IntToEdge(Edge).Node; 00564 // use <= because we are trying to push the new (non-existent) nodes as far as possible 00565 if ( Dec_GraphNode(pGraph, NodeOld)->Level <= Dec_GraphNode(pGraph, NodeNew)->Level ) 00566 vEdges->pArray[i+1] = vEdges->pArray[i]; 00567 else 00568 break; 00569 } 00570 vEdges->pArray[i+1] = Edge; 00571 }
Dec_Graph_t * Abc_NodeEvaluateDsd | ( | Abc_ManRst_t * | pManRst, | |
Dsd_Node_t * | pNodeDsd, | |||
Abc_Obj_t * | pRoot, | |||
int | Required, | |||
int | nNodesSaved, | |||
int * | pnNodesAdded | |||
) | [static] |
Function*************************************************************
Synopsis [Evaluation one DSD.]
Description []
SideEffects []
SeeAlso []
Definition at line 902 of file abcRestruct.c.
00903 { 00904 Dec_Graph_t * pGraph; 00905 Dec_Edge_t gEdge; 00906 Abc_Obj_t * pLeaf; 00907 Dec_Node_t * pNode; 00908 int i; 00909 00910 // create the graph and set the leaves 00911 pGraph = Dec_GraphCreate( Vec_PtrSize(pManRst->vLeaves) ); 00912 Dec_GraphForEachLeaf( pGraph, pNode, i ) 00913 { 00914 pLeaf = Vec_PtrEntry( pManRst->vLeaves, i ); 00915 pNode->pFunc = pLeaf; 00916 pNode->Level = pLeaf->Level; 00917 } 00918 00919 // create the decomposition structure from the DSD 00920 *pnNodesAdded = 0; 00921 gEdge = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pNodeDsd, Required, nNodesSaved, pnNodesAdded ); 00922 if ( gEdge.Node > 1000 ) // infeasible 00923 { 00924 *pnNodesAdded = -1; 00925 Dec_GraphFree( pGraph ); 00926 return NULL; 00927 } 00928 00929 // quit if the root node is the same 00930 pLeaf = Dec_GraphNode( pGraph, gEdge.Node )->pFunc; 00931 if ( Abc_ObjRegular(pLeaf) == pRoot ) 00932 { 00933 *pnNodesAdded = -1; 00934 Dec_GraphFree( pGraph ); 00935 return NULL; 00936 } 00937 00938 Dec_GraphSetRoot( pGraph, gEdge ); 00939 return pGraph; 00940 }
Dec_Edge_t Abc_NodeEvaluateDsd_rec | ( | Dec_Graph_t * | pGraph, | |
Abc_ManRst_t * | pManRst, | |||
Dsd_Node_t * | pNodeDsd, | |||
int | Required, | |||
int | nNodesSaved, | |||
int * | pnNodesAdded | |||
) |
Function*************************************************************
Synopsis [Evaluation one DSD.]
Description []
SideEffects []
SeeAlso []
Definition at line 584 of file abcRestruct.c.
00585 { 00586 Dec_Edge_t eNode1, eNode2, eNode3, eResult, eQuit = { 0, 2006 }; 00587 Abc_Obj_t * pNode1, * pNode2, * pNode3, * pNode4, * pTemp; 00588 Dsd_Node_t * pChildDsd; 00589 Dsd_Type_t DecType; 00590 Vec_Int_t * vEdges; 00591 int Level1, Level2, Level3, Level4; 00592 int i, Index, fCompl, Type; 00593 00594 // remove the complemented attribute 00595 fCompl = Dsd_IsComplement( pNodeDsd ); 00596 pNodeDsd = Dsd_Regular( pNodeDsd ); 00597 00598 // consider the trivial case 00599 DecType = Dsd_NodeReadType( pNodeDsd ); 00600 if ( DecType == DSD_NODE_BUF ) 00601 { 00602 Index = Dsd_NodeReadFunc(pNodeDsd)->index; 00603 assert( Index < Dec_GraphLeaveNum(pGraph) ); 00604 eResult = Dec_EdgeCreate( Index, fCompl ); 00605 return eResult; 00606 } 00607 assert( DecType == DSD_NODE_OR || DecType == DSD_NODE_EXOR || DecType == DSD_NODE_PRIME ); 00608 00609 // solve the problem for the children 00610 vEdges = Vec_IntAlloc( Dsd_NodeReadDecsNum(pNodeDsd) ); 00611 Dsd_NodeForEachChild( pNodeDsd, i, pChildDsd ) 00612 { 00613 eResult = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pChildDsd, Required, nNodesSaved, pnNodesAdded ); 00614 if ( eResult.Node == eQuit.Node ) // infeasible 00615 { 00616 Vec_IntFree( vEdges ); 00617 return eQuit; 00618 } 00619 // order the inputs only if this is OR or EXOR 00620 if ( DecType == DSD_NODE_PRIME ) 00621 Vec_IntPush( vEdges, Dec_EdgeToInt(eResult) ); 00622 else 00623 Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eResult) ); 00624 } 00625 // the edges are sorted by the level of their nodes in decreasing order 00626 00627 00628 // consider special cases 00629 if ( DecType == DSD_NODE_OR ) 00630 { 00631 // try to balance the nodes by delay 00632 assert( Vec_IntSize(vEdges) > 1 ); 00633 while ( Vec_IntSize(vEdges) > 1 ) 00634 { 00635 // permute the last two entries 00636 if ( Vec_IntSize(vEdges) > 2 ) 00637 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 0 ); 00638 // get the two last nodes 00639 eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) ); 00640 eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) ); 00641 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc; 00642 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc; 00643 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl ); 00644 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl ); 00645 // check if the new node exists 00646 pNode3 = NULL; 00647 if ( pNode1 && pNode2 ) 00648 { 00649 pNode3 = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); 00650 pNode3 = !pNode3? NULL : Abc_ObjNot(pNode3); 00651 } 00652 // create the new node 00653 eNode3 = Dec_GraphAddNodeOr( pGraph, eNode1, eNode2 ); 00654 // set level 00655 Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level; 00656 Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level; 00657 Dec_GraphNode( pGraph, eNode3.Node )->Level = 1 + ABC_MAX(Level1, Level2); 00658 // get the new node if possible 00659 if ( pNode3 ) 00660 { 00661 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl); 00662 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level; 00663 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level ); 00664 } 00665 if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) ) 00666 { 00667 (*pnNodesAdded)++; 00668 if ( *pnNodesAdded > nNodesSaved ) 00669 { 00670 Vec_IntFree( vEdges ); 00671 return eQuit; 00672 } 00673 } 00674 // add the resulting node to the form 00675 Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) ); 00676 } 00677 // get the last node 00678 eResult = Dec_IntToEdge( Vec_IntPop(vEdges) ); 00679 Vec_IntFree( vEdges ); 00680 // complement the graph if the node was complemented 00681 eResult.fCompl ^= fCompl; 00682 return eResult; 00683 } 00684 if ( DecType == DSD_NODE_EXOR ) 00685 { 00686 // try to balance the nodes by delay 00687 assert( Vec_IntSize(vEdges) > 1 ); 00688 while ( Vec_IntSize(vEdges) > 1 ) 00689 { 00690 // permute the last two entries 00691 if ( Vec_IntSize(vEdges) > 2 ) 00692 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 1 ); 00693 // get the two last nodes 00694 eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) ); 00695 eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) ); 00696 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc; 00697 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc; 00698 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl ); 00699 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl ); 00700 // check if the new node exists 00701 Type = 0; 00702 pNode3 = NULL; 00703 if ( pNode1 && pNode2 ) 00704 pNode3 = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, &Type ); 00705 // create the new node 00706 eNode3 = Dec_GraphAddNodeXor( pGraph, eNode1, eNode2, Type ); // should have the same structure as in AIG 00707 // set level 00708 Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level; 00709 Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level; 00710 Dec_GraphNode( pGraph, eNode3.Node )->Level = 2 + ABC_MAX(Level1, Level2); 00711 // get the new node if possible 00712 if ( pNode3 ) 00713 { 00714 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl); 00715 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level; 00716 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level ); 00717 } 00718 if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) ) 00719 { 00720 (*pnNodesAdded)++; 00721 if ( !pNode1 || !pNode2 ) 00722 (*pnNodesAdded) += 2; 00723 else if ( Type == 0 ) 00724 { 00725 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) ); 00726 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00727 (*pnNodesAdded)++; 00728 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode2 ); 00729 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00730 (*pnNodesAdded)++; 00731 } 00732 else 00733 { 00734 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) ); 00735 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00736 (*pnNodesAdded)++; 00737 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 ); 00738 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00739 (*pnNodesAdded)++; 00740 } 00741 if ( *pnNodesAdded > nNodesSaved ) 00742 { 00743 Vec_IntFree( vEdges ); 00744 return eQuit; 00745 } 00746 } 00747 // add the resulting node to the form 00748 Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) ); 00749 } 00750 // get the last node 00751 eResult = Dec_IntToEdge( Vec_IntPop(vEdges) ); 00752 Vec_IntFree( vEdges ); 00753 // complement the graph if the node is complemented 00754 eResult.fCompl ^= fCompl; 00755 return eResult; 00756 } 00757 if ( DecType == DSD_NODE_PRIME ) 00758 { 00759 DdNode * bLocal, * bVar, * bCofT, * bCofE; 00760 bLocal = Dsd_TreeGetPrimeFunction( pManRst->dd, pNodeDsd ); Cudd_Ref( bLocal ); 00761 //Extra_bddPrint( pManRst->dd, bLocal ); 00762 00763 bVar = pManRst->dd->vars[0]; 00764 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) ); Cudd_Ref( bCofE ); 00765 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar ); Cudd_Ref( bCofT ); 00766 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) ) 00767 { 00768 Cudd_RecursiveDeref( pManRst->dd, bCofE ); 00769 Cudd_RecursiveDeref( pManRst->dd, bCofT ); 00770 bVar = pManRst->dd->vars[1]; 00771 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) ); Cudd_Ref( bCofE ); 00772 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar ); Cudd_Ref( bCofT ); 00773 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) ) 00774 { 00775 Cudd_RecursiveDeref( pManRst->dd, bCofE ); 00776 Cudd_RecursiveDeref( pManRst->dd, bCofT ); 00777 bVar = pManRst->dd->vars[2]; 00778 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) ); Cudd_Ref( bCofE ); 00779 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar ); Cudd_Ref( bCofT ); 00780 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) ) 00781 { 00782 Cudd_RecursiveDeref( pManRst->dd, bCofE ); 00783 Cudd_RecursiveDeref( pManRst->dd, bCofT ); 00784 Cudd_RecursiveDeref( pManRst->dd, bLocal ); 00785 Vec_IntFree( vEdges ); 00786 return eQuit; 00787 } 00788 } 00789 } 00790 Cudd_RecursiveDeref( pManRst->dd, bLocal ); 00791 // we found the control variable (bVar) and the var-cofactors (bCofT, bCofE) 00792 00793 // find the graph nodes 00794 eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, bVar->index) ); 00795 eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofT)->index) ); 00796 eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofE)->index) ); 00797 // add the complements to the graph nodes 00798 eNode2.fCompl ^= Cudd_IsComplement(bCofT); 00799 eNode3.fCompl ^= Cudd_IsComplement(bCofE); 00800 00801 // because the cofactors are vars, we can just as well deref them here 00802 Cudd_RecursiveDeref( pManRst->dd, bCofE ); 00803 Cudd_RecursiveDeref( pManRst->dd, bCofT ); 00804 00805 // find the ABC nodes 00806 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc; 00807 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc; 00808 pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc; 00809 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl ); 00810 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl ); 00811 pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl ); 00812 00813 // check if the new node exists 00814 Type = 0; 00815 pNode4 = NULL; 00816 if ( pNode1 && pNode2 && pNode3 ) 00817 pNode4 = Abc_AigMuxLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, pNode3, &Type ); 00818 00819 // create the new node 00820 eResult = Dec_GraphAddNodeMux( pGraph, eNode1, eNode2, eNode3, Type ); // should have the same structure as AIG 00821 00822 // set level 00823 Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level; 00824 Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level; 00825 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level; 00826 Dec_GraphNode( pGraph, eResult.Node )->Level = 2 + ABC_MAX( ABC_MAX(Level1, Level2), Level3 ); 00827 // get the new node if possible 00828 if ( pNode4 ) 00829 { 00830 Dec_GraphNode( pGraph, eResult.Node )->pFunc = Abc_ObjNotCond(pNode4, eResult.fCompl); 00831 Level4 = Dec_GraphNode( pGraph, eResult.Node )->Level; 00832 assert( Required == ABC_INFINITY || Level4 == (int)Abc_ObjRegular(pNode4)->Level ); 00833 } 00834 if ( !pNode4 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode4)) ) 00835 { 00836 (*pnNodesAdded)++; 00837 if ( Type == 0 ) 00838 { 00839 if ( !pNode1 || !pNode2 ) 00840 (*pnNodesAdded)++; 00841 else 00842 { 00843 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 ); 00844 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00845 (*pnNodesAdded)++; 00846 } 00847 if ( !pNode1 || !pNode3 ) 00848 (*pnNodesAdded)++; 00849 else 00850 { 00851 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode3 ); 00852 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00853 (*pnNodesAdded)++; 00854 } 00855 } 00856 else 00857 { 00858 if ( !pNode1 || !pNode2 ) 00859 (*pnNodesAdded)++; 00860 else 00861 { 00862 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) ); 00863 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00864 (*pnNodesAdded)++; 00865 } 00866 if ( !pNode1 || !pNode3 ) 00867 (*pnNodesAdded)++; 00868 else 00869 { 00870 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) ); 00871 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) ) 00872 (*pnNodesAdded)++; 00873 } 00874 } 00875 if ( *pnNodesAdded > nNodesSaved ) 00876 { 00877 Vec_IntFree( vEdges ); 00878 return eQuit; 00879 } 00880 } 00881 00882 Vec_IntFree( vEdges ); 00883 // complement the graph if the node was complemented 00884 eResult.fCompl ^= fCompl; 00885 return eResult; 00886 } 00887 Vec_IntFree( vEdges ); 00888 return eQuit; 00889 }
Dec_Graph_t* Abc_NodeMffcConstants | ( | Abc_ManRst_t * | p, | |
Vec_Int_t * | vSims | |||
) |
Function*************************************************************
Synopsis [Detect contants.]
Description []
SideEffects []
SeeAlso []
Definition at line 1248 of file abcRestruct.c.
01249 { 01250 Dec_Graph_t * pGraph; 01251 unsigned uRoot; 01252 // get the root node 01253 uRoot = (unsigned)Vec_IntEntryLast( vSims ); 01254 // get the graph if the node looks constant 01255 if ( uRoot == 0 ) 01256 pGraph = Dec_GraphCreateConst0(); 01257 else if ( uRoot == ~(unsigned)0 ) 01258 pGraph = Dec_GraphCreateConst1(); 01259 // check the graph 01260 if ( Abc_NodeCheckFull( p, pGraph ) ) 01261 return pGraph; 01262 Dec_GraphFree( pGraph ); 01263 return NULL; 01264 }
Dec_Graph_t* Abc_NodeMffcDoubleNode | ( | Abc_ManRst_t * | p, | |
Vec_Int_t * | vSims, | |||
int | nNodes, | |||
Vec_Int_t * | vOnes | |||
) |
Function*************************************************************
Synopsis [Detect single non-overlaps.]
Description []
SideEffects []
SeeAlso []
Definition at line 1356 of file abcRestruct.c.
01357 { 01358 // Dec_Graph_t * pGraph; 01359 // unsigned uRoot, uNode; 01360 // int i; 01361 01362 01363 return NULL; 01364 }
Function*************************************************************
Synopsis [Performs simulation.]
Description []
SideEffects []
SeeAlso []
Definition at line 1198 of file abcRestruct.c.
01199 { 01200 Abc_Obj_t * pObj; 01201 unsigned uData0, uData1, uData; 01202 int i; 01203 // initialize random simulation data 01204 Vec_IntClear( vSims ); 01205 Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves ) 01206 { 01207 uData = (unsigned)Vec_IntEntry( vRands, i ); 01208 pObj->pData = (void *)uData; 01209 Vec_IntPush( vSims, uData ); 01210 } 01211 // simulate 01212 Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves ) 01213 { 01214 uData0 = (unsigned)Abc_ObjFanin0(pObj)->pData; 01215 uData1 = (unsigned)Abc_ObjFanin1(pObj)->pData; 01216 uData = (Abc_ObjFaninC0(pObj)? ~uData0 : uData0) & (Abc_ObjFaninC1(pObj)? ~uData1 : uData1); 01217 pObj->pData = (void *)uData; 01218 Vec_IntPush( vSims, uData ); 01219 } 01220 }
Dec_Graph_t* Abc_NodeMffcSingleNode | ( | Abc_ManRst_t * | p, | |
Vec_Int_t * | vSims, | |||
int | nNodes, | |||
Vec_Int_t * | vOnes | |||
) |
Function*************************************************************
Synopsis [Detect single non-overlaps.]
Description []
SideEffects []
SeeAlso []
Definition at line 1320 of file abcRestruct.c.
01321 { 01322 Dec_Graph_t * pGraph; 01323 Dec_Edge_t eNode0, eNode1, eRoot; 01324 unsigned uRoot; 01325 int i, k; 01326 uRoot = (unsigned)Vec_IntEntryLast( vSims ); 01327 for ( i = 0; i < vOnes->nSize; i++ ) 01328 for ( k = i+1; k < vOnes->nSize; k++ ) 01329 if ( ~uRoot == ((unsigned)vOnes->pArray[i] | (unsigned)vOnes->pArray[k]) ) 01330 { 01331 eNode0 = Dec_IntToEdge( vOnes->pArray[i] ^ 1 ); 01332 eNode1 = Dec_IntToEdge( vOnes->pArray[k] ^ 1 ); 01333 pGraph = Dec_GraphCreate( 2 ); 01334 Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, eNode0.Node ); 01335 Dec_GraphNode( pGraph, 1 )->pFunc = Vec_PtrEntry( p->vDecs, eNode1.Node ); 01336 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 ); 01337 Dec_GraphSetRoot( pGraph, eRoot ); 01338 if ( Abc_NodeCheckFull( p, pGraph ) ) 01339 return pGraph; 01340 Dec_GraphFree( pGraph ); 01341 } 01342 return NULL; 01343 }
Dec_Graph_t* Abc_NodeMffcSingleVar | ( | Abc_ManRst_t * | p, | |
Vec_Int_t * | vSims, | |||
int | nNodes, | |||
Vec_Int_t * | vOnes | |||
) |
Function*************************************************************
Synopsis [Detect single non-overlaps.]
Description []
SideEffects []
SeeAlso []
Definition at line 1277 of file abcRestruct.c.
01278 { 01279 Dec_Graph_t * pGraph; 01280 unsigned uRoot, uNode; 01281 int i; 01282 01283 Vec_IntClear( vOnes ); 01284 Vec_IntClear( p->vBinate ); 01285 uRoot = (unsigned)Vec_IntEntryLast( vSims ); 01286 for ( i = 0; i < nNodes; i++ ) 01287 { 01288 uNode = (unsigned)Vec_IntEntry( vSims, i ); 01289 if ( uRoot == uNode || uRoot == ~uNode ) 01290 { 01291 pGraph = Dec_GraphCreate( 1 ); 01292 Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, i ); 01293 Dec_GraphSetRoot( pGraph, Dec_IntToEdge( (int)(uRoot == ~uNode) ) ); 01294 // check the graph 01295 if ( Abc_NodeCheckFull( p, pGraph ) ) 01296 return pGraph; 01297 Dec_GraphFree( pGraph ); 01298 } 01299 if ( (uRoot & uNode) == 0 ) 01300 Vec_IntPush( vOnes, i << 1 ); 01301 else if ( (uRoot & ~uNode) == 0 ) 01302 Vec_IntPush( vOnes, (i << 1) + 1 ); 01303 else 01304 Vec_IntPush( p->vBinate, i ); 01305 } 01306 return NULL; 01307 }
Dec_Graph_t * Abc_NodeRestructure | ( | Abc_ManRst_t * | p, | |
Abc_Obj_t * | pNode, | |||
Cut_Cut_t * | pCutList | |||
) | [static] |
Function*************************************************************
Synopsis [Starts the cut manager for rewriting.]
Description []
SideEffects []
SeeAlso []
Definition at line 278 of file abcRestruct.c.
00279 { 00280 Dec_Graph_t * pGraph; 00281 Cut_Cut_t * pCut; 00282 // int nCuts; 00283 p->nNodesConsidered++; 00284 /* 00285 // count the number of cuts with four inputs or more 00286 nCuts = 0; 00287 for ( pCut = pCutList; pCut; pCut = pCut->pNext ) 00288 nCuts += (int)(pCut->nLeaves > 3); 00289 printf( "-----------------------------------\n" ); 00290 printf( "Node %6d : Factor-cuts = %5d.\n", pNode->Id, nCuts ); 00291 */ 00292 // go through the interesting cuts 00293 for ( pCut = pCutList; pCut; pCut = pCut->pNext ) 00294 { 00295 if ( pCut->nLeaves < 4 ) 00296 continue; 00297 if ( pGraph = Abc_NodeRestructureCut( p, pNode, pCut ) ) 00298 return pGraph; 00299 } 00300 return NULL; 00301 }
Dec_Graph_t * Abc_NodeRestructureCut | ( | Abc_ManRst_t * | p, | |
Abc_Obj_t * | pRoot, | |||
Cut_Cut_t * | pCut | |||
) | [static] |
Function*************************************************************
Synopsis [Starts the cut manager for rewriting.]
Description []
SideEffects []
SeeAlso []
Definition at line 314 of file abcRestruct.c.
00315 { 00316 Dec_Graph_t * pGraph; 00317 Dsd_Node_t * pNodeDsd; 00318 Abc_Obj_t * pLeaf; 00319 DdNode * bFunc; 00320 int nNodesSaved, nNodesAdded; 00321 int Required, nMaxSize, clk, i; 00322 int fVeryVerbose = 0; 00323 00324 p->nCutsConsidered++; 00325 00326 // get the required time for the node 00327 Required = p->fUpdateLevel? Abc_ObjRequiredLevel(pRoot) : ABC_INFINITY; 00328 00329 // collect the leaves of the cut 00330 Vec_PtrClear( p->vLeaves ); 00331 for ( i = 0; i < (int)pCut->nLeaves; i++ ) 00332 { 00333 pLeaf = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]); 00334 if ( pLeaf == NULL ) // the so-called "bad cut phenomenon" is due to removed nodes 00335 return NULL; 00336 Vec_PtrPush( p->vLeaves, pLeaf ); 00337 } 00338 00339 if ( pRoot->Id == 29 ) 00340 { 00341 int x = 0; 00342 } 00343 00344 clk = clock(); 00345 // collect the internal nodes of the cut 00346 // Abc_NodeConeCollect( &pRoot, 1, p->vLeaves, p->vVisited, 0 ); 00347 // derive the BDD of the cut 00348 bFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pRoot, p->vLeaves, p->vVisited ); Cudd_Ref( bFunc ); 00349 p->timeBdd += clock() - clk; 00350 00351 // consider the special case, when the function is a constant 00352 if ( Cudd_IsConstant(bFunc) ) 00353 { 00354 p->nLastGain = Abc_NodeMffcSize( pRoot ); 00355 p->nNodesGained += p->nLastGain; 00356 p->nNodesRestructured++; 00357 Cudd_RecursiveDeref( p->dd, bFunc ); 00358 if ( Cudd_IsComplement(bFunc) ) 00359 return Dec_GraphCreateConst0(); 00360 return Dec_GraphCreateConst1(); 00361 } 00362 00363 clk = clock(); 00364 // try disjoint support decomposition 00365 pNodeDsd = Dsd_DecomposeOne( p->pManDsd, bFunc ); 00366 p->timeDsd += clock() - clk; 00367 00368 // skip nodes with non-decomposable blocks 00369 Dsd_TreeNodeGetInfoOne( pNodeDsd, NULL, &nMaxSize ); 00370 if ( nMaxSize > 3 ) 00371 { 00372 Cudd_RecursiveDeref( p->dd, bFunc ); 00373 return NULL; 00374 } 00375 00376 00377 /* 00378 // skip nodes that cannot be improved 00379 if ( Vec_PtrSize(p->vVisited) <= Dsd_TreeGetAigCost(pNodeDsd) ) 00380 { 00381 Cudd_RecursiveDeref( p->dd, bFunc ); 00382 return NULL; 00383 } 00384 */ 00385 00386 p->nCutsExplored++; 00387 00388 // mark the fanin boundary 00389 // (can mark only essential fanins, belonging to bNodeFunc!) 00390 Vec_PtrForEachEntry( p->vLeaves, pLeaf, i ) 00391 pLeaf->vFanouts.nSize++; 00392 // label MFFC with current traversal ID 00393 Abc_NtkIncrementTravId( pRoot->pNtk ); 00394 nNodesSaved = Abc_NodeMffcLabelAig( pRoot ); 00395 // unmark the fanin boundary and set the fanins as leaves in the form 00396 Vec_PtrForEachEntry( p->vLeaves, pLeaf, i ) 00397 pLeaf->vFanouts.nSize--; 00398 /* 00399 if ( nNodesSaved < 3 ) 00400 { 00401 Cudd_RecursiveDeref( p->dd, bFunc ); 00402 return NULL; 00403 } 00404 */ 00405 00406 /* 00407 printf( "%5d : Cut-size = %d. Old AIG = %2d. New AIG = %2d. Old MFFC = %2d.\n", 00408 pRoot->Id, pCut->nLeaves, Vec_PtrSize(p->vVisited), Dsd_TreeGetAigCost(pNodeDsd), 00409 nNodesSaved ); 00410 Dsd_NodePrint( stdout, pNodeDsd ); 00411 00412 Abc_RestructNodeDivisors( p, pRoot ); 00413 00414 if ( pRoot->Id == 433 ) 00415 { 00416 int x = 0; 00417 } 00418 */ 00419 // Abc_RestructNodeDivisors( p, pRoot, nNodesSaved ); 00420 00421 00422 // detect how many new nodes will be added (while taking into account reused nodes) 00423 clk = clock(); 00424 if ( nMaxSize > 3 ) 00425 pGraph = NULL; 00426 else 00427 pGraph = Abc_NodeEvaluateDsd( p, pNodeDsd, pRoot, Required, nNodesSaved, &nNodesAdded ); 00428 // pGraph = NULL; 00429 p->timeEval += clock() - clk; 00430 00431 // quit if there is no improvement 00432 if ( pGraph == NULL || nNodesAdded == -1 || nNodesAdded == nNodesSaved && !p->fUseZeros ) 00433 { 00434 Cudd_RecursiveDeref( p->dd, bFunc ); 00435 if ( pGraph ) Dec_GraphFree( pGraph ); 00436 return NULL; 00437 } 00438 00439 /* 00440 // print stats 00441 printf( "%5d : Cut-size = %d. Old AIG = %2d. New AIG = %2d. Old MFFC = %2d. New MFFC = %2d. Gain = %d.\n", 00442 pRoot->Id, pCut->nLeaves, Vec_PtrSize(p->vVisited), Dsd_TreeGetAigCost(pNodeDsd), 00443 nNodesSaved, nNodesAdded, (nNodesAdded == -1)? 0 : nNodesSaved-nNodesAdded ); 00444 // Dsd_NodePrint( stdout, pNodeDsd ); 00445 // Dec_GraphPrint( stdout, pGraph, NULL, NULL ); 00446 */ 00447 00448 // compute the total gain in the number of nodes 00449 p->nLastGain = nNodesSaved - nNodesAdded; 00450 p->nNodesGained += p->nLastGain; 00451 p->nNodesRestructured++; 00452 00453 // report the progress 00454 if ( fVeryVerbose ) 00455 { 00456 printf( "Node %6s : ", Abc_ObjName(pRoot) ); 00457 printf( "Cone = %2d. ", p->vLeaves->nSize ); 00458 printf( "BDD = %2d. ", Cudd_DagSize(bFunc) ); 00459 printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pGraph) ); 00460 printf( "MFFC = %2d. ", nNodesSaved ); 00461 printf( "Add = %2d. ", nNodesAdded ); 00462 printf( "GAIN = %2d. ", p->nLastGain ); 00463 printf( "\n" ); 00464 } 00465 Cudd_RecursiveDeref( p->dd, bFunc ); 00466 return pGraph; 00467 }
Dec_Graph_t* Abc_NodeResubEval | ( | Abc_ManRst_t * | p, | |
Abc_Obj_t * | pRoot, | |||
Cut_Cut_t * | pCut | |||
) |
Function*************************************************************
Synopsis [Evaluates resubstution of one cut.]
Description [Returns the graph to add if any.]
SideEffects []
SeeAlso []
Definition at line 1377 of file abcRestruct.c.
01378 { 01379 Dec_Graph_t * pGraph; 01380 int nNodesSaved; 01381 01382 // collect the nodes in the cut 01383 if ( !Abc_Abc_NodeResubCollectDivs( p, pRoot, pCut ) ) 01384 return NULL; 01385 01386 // label MFFC and count its size 01387 nNodesSaved = Abc_NodeResubMffc( p, p->vDecs, pCut->nLeaves, pRoot ); 01388 assert( nNodesSaved > 0 ); 01389 01390 // simulate MFFC 01391 Abc_NodeMffcSimulate( p->vDecs, pCut->nLeaves, p->vRands, p->vSims ); 01392 01393 // check for constant output 01394 pGraph = Abc_NodeMffcConstants( p, p->vSims ); 01395 if ( pGraph ) 01396 { 01397 p->nNodesGained += nNodesSaved; 01398 p->nNodesRestructured++; 01399 return pGraph; 01400 } 01401 01402 // check for one literal (fill up the ones array) 01403 pGraph = Abc_NodeMffcSingleVar( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes ); 01404 if ( pGraph ) 01405 { 01406 p->nNodesGained += nNodesSaved; 01407 p->nNodesRestructured++; 01408 return pGraph; 01409 } 01410 if ( nNodesSaved == 1 ) 01411 return NULL; 01412 01413 // look for one node 01414 pGraph = Abc_NodeMffcSingleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes ); 01415 if ( pGraph ) 01416 { 01417 p->nNodesGained += nNodesSaved - 1; 01418 p->nNodesRestructured++; 01419 return pGraph; 01420 } 01421 if ( nNodesSaved == 2 ) 01422 return NULL; 01423 01424 // look for two nodes 01425 pGraph = Abc_NodeMffcDoubleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes ); 01426 if ( pGraph ) 01427 { 01428 p->nNodesGained += nNodesSaved - 2; 01429 p->nNodesRestructured++; 01430 return pGraph; 01431 } 01432 if ( nNodesSaved == 3 ) 01433 return NULL; 01434 /* 01435 // look for MUX/EXOR 01436 pGraph = Abc_NodeMffcMuxNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved ); 01437 if ( pGraph ) 01438 { 01439 p->nNodesGained += nNodesSaved - 1; 01440 p->nNodesRestructured++; 01441 return pGraph; 01442 } 01443 */ 01444 return NULL; 01445 }
int Abc_NodeResubMffc | ( | Abc_ManRst_t * | p, | |
Vec_Ptr_t * | vDecs, | |||
int | nLeaves, | |||
Abc_Obj_t * | pRoot | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 1159 of file abcRestruct.c.
01160 { 01161 Abc_Obj_t * pObj; 01162 int Counter, i, k; 01163 // increment the traversal ID for the leaves 01164 Abc_NtkIncrementTravId( pRoot->pNtk ); 01165 // label the leaves 01166 Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves ) 01167 Abc_NodeSetTravIdCurrent( pObj ); 01168 // make sure the node is in the cone and is no one of the leaves 01169 assert( Abc_NodeIsTravIdPrevious(pRoot) ); 01170 Counter = Abc_NodeResubMffc_rec( pRoot ); 01171 // move the labeled nodes to the end 01172 Vec_PtrClear( p->vTemp ); 01173 k = 0; 01174 Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves ) 01175 if ( Abc_NodeIsTravIdCurrent(pObj) ) 01176 Vec_PtrPush( p->vTemp, pObj ); 01177 else 01178 Vec_PtrWriteEntry( vDecs, k++, pObj ); 01179 // add the labeled nodes 01180 Vec_PtrForEachEntry( p->vTemp, pObj, i ) 01181 Vec_PtrWriteEntry( vDecs, k++, pObj ); 01182 assert( k == Vec_PtrSize(p->vDecs) ); 01183 assert( pRoot == Vec_PtrEntryLast(p->vDecs) ); 01184 return Counter; 01185 }
int Abc_NodeResubMffc_rec | ( | Abc_Obj_t * | pNode | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 1139 of file abcRestruct.c.
01140 { 01141 if ( Abc_NodeIsTravIdCurrent(pNode) ) 01142 return 0; 01143 Abc_NodeSetTravIdCurrent( pNode ); 01144 return 1 + Abc_NodeResubMffc_rec( Abc_ObjFanin0(pNode) ) + 01145 Abc_NodeResubMffc_rec( Abc_ObjFanin1(pNode) ); 01146 }
Dec_Graph_t * Abc_NodeResubstitute | ( | Abc_ManRst_t * | p, | |
Abc_Obj_t * | pNode, | |||
Cut_Cut_t * | pCutList | |||
) | [static] |
Function*************************************************************
Synopsis [Performs resubstution.]
Description []
SideEffects []
SeeAlso []
Definition at line 1458 of file abcRestruct.c.
01459 { 01460 Dec_Graph_t * pGraph, * pGraphBest = NULL; 01461 Cut_Cut_t * pCut; 01462 int nCuts; 01463 p->nNodesConsidered++; 01464 01465 // count the number of cuts with four inputs or more 01466 nCuts = 0; 01467 for ( pCut = pCutList; pCut; pCut = pCut->pNext ) 01468 nCuts += (int)(pCut->nLeaves > 3); 01469 printf( "-----------------------------------\n" ); 01470 printf( "Node %6d : Factor-cuts = %5d.\n", pNode->Id, nCuts ); 01471 01472 // go through the interesting cuts 01473 for ( pCut = pCutList; pCut; pCut = pCut->pNext ) 01474 { 01475 if ( pCut->nLeaves < 4 ) 01476 continue; 01477 pGraph = Abc_NodeResubEval( p, pNode, pCut ); 01478 if ( pGraph == NULL ) 01479 continue; 01480 if ( !pGraphBest || Dec_GraphNodeNum(pGraph) < Dec_GraphNodeNum(pGraphBest) ) 01481 { 01482 if ( pGraphBest ) 01483 Dec_GraphFree(pGraphBest); 01484 pGraphBest = pGraph; 01485 } 01486 else 01487 Dec_GraphFree(pGraph); 01488 } 01489 return pGraphBest; 01490 }
void Abc_NtkManRstPrintStats | ( | Abc_ManRst_t * | p | ) | [static] |
Function*************************************************************
Synopsis [Stops the resynthesis manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 1066 of file abcRestruct.c.
01067 { 01068 printf( "Refactoring statistics:\n" ); 01069 printf( "Nodes considered = %8d.\n", p->nNodesConsidered ); 01070 printf( "Cuts considered = %8d.\n", p->nCutsConsidered ); 01071 printf( "Cuts explored = %8d.\n", p->nCutsExplored ); 01072 printf( "Nodes restructured = %8d.\n", p->nNodesRestructured ); 01073 printf( "Calculated gain = %8d.\n", p->nNodesGained ); 01074 PRT( "Cuts ", p->timeCut ); 01075 PRT( "Resynthesis", p->timeRes ); 01076 PRT( " BDD ", p->timeBdd ); 01077 PRT( " DSD ", p->timeDsd ); 01078 PRT( " Eval ", p->timeEval ); 01079 PRT( "AIG update ", p->timeNtk ); 01080 PRT( "TOTAL ", p->timeTotal ); 01081 }
Abc_ManRst_t * Abc_NtkManRstStart | ( | int | nCutMax, | |
bool | fUpdateLevel, | |||
bool | fUseZeros, | |||
bool | fVerbose | |||
) | [static] |
Function*************************************************************
Synopsis [Starts the resynthesis manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 994 of file abcRestruct.c.
00995 { 00996 Abc_ManRst_t * p; 00997 p = ALLOC( Abc_ManRst_t, 1 ); 00998 memset( p, 0, sizeof(Abc_ManRst_t) ); 00999 // set the parameters 01000 p->nCutMax = nCutMax; 01001 p->fUpdateLevel = fUpdateLevel; 01002 p->fUseZeros = fUseZeros; 01003 p->fVerbose = fVerbose; 01004 // start the BDD manager 01005 p->dd = Cudd_Init( p->nCutMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 ); 01006 Cudd_zddVarsFromBddVars( p->dd, 2 ); 01007 // start the DSD manager 01008 p->pManDsd = Dsd_ManagerStart( p->dd, p->dd->size, 0 ); 01009 // other temp datastructures 01010 p->vVisited = Vec_PtrAlloc( 100 ); 01011 p->vLeaves = Vec_PtrAlloc( 100 ); 01012 p->vDecs = Vec_PtrAlloc( 100 ); 01013 p->vTemp = Vec_PtrAlloc( 100 ); 01014 p->vSims = Vec_IntAlloc( 100 ); 01015 p->vOnes = Vec_IntAlloc( 100 ); 01016 p->vBinate = Vec_IntAlloc( 100 ); 01017 p->vTwos = Vec_IntAlloc( 100 ); 01018 p->vRands = Vec_IntAlloc( 20 ); 01019 01020 { 01021 int i; 01022 for ( i = 0; i < 20; i++ ) 01023 Vec_IntPush( p->vRands, (int)RST_RANDOM_UNSIGNED ); 01024 } 01025 return p; 01026 }
void Abc_NtkManRstStop | ( | Abc_ManRst_t * | p | ) | [static] |
Function*************************************************************
Synopsis [Stops the resynthesis manager.]
Description []
SideEffects []
SeeAlso []
Definition at line 1039 of file abcRestruct.c.
01040 { 01041 Dsd_ManagerStop( p->pManDsd ); 01042 Extra_StopManager( p->dd ); 01043 Vec_PtrFree( p->vDecs ); 01044 Vec_PtrFree( p->vLeaves ); 01045 Vec_PtrFree( p->vVisited ); 01046 Vec_PtrFree( p->vTemp ); 01047 Vec_IntFree( p->vSims ); 01048 Vec_IntFree( p->vOnes ); 01049 Vec_IntFree( p->vBinate ); 01050 Vec_IntFree( p->vTwos ); 01051 Vec_IntFree( p->vRands ); 01052 free( p ); 01053 }
int Abc_NtkRestructure | ( | Abc_Ntk_t * | pNtk, | |
int | nCutMax, | |||
bool | fUpdateLevel, | |||
bool | fUseZeros, | |||
bool | fVerbose | |||
) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Implements AIG restructuring.]
Description []
SideEffects []
SeeAlso []
Definition at line 97 of file abcRestruct.c.
00098 { 00099 ProgressBar * pProgress; 00100 Abc_ManRst_t * pManRst; 00101 Cut_Man_t * pManCut; 00102 Cut_Cut_t * pCutList; 00103 Dec_Graph_t * pGraph; 00104 Abc_Obj_t * pNode; 00105 int clk, clkStart = clock(); 00106 int fMulti = 1; 00107 int fResub = 0; 00108 int i, nNodes; 00109 00110 assert( Abc_NtkIsStrash(pNtk) ); 00111 // cleanup the AIG 00112 Abc_AigCleanup(pNtk->pManFunc); 00113 Abc_NtkCleanCopy(pNtk); 00114 00115 // compute the reverse levels if level update is requested 00116 if ( fUpdateLevel ) 00117 Abc_NtkStartReverseLevels( pNtk, 0 ); 00118 00119 // start the restructuring manager 00120 pManRst = Abc_NtkManRstStart( nCutMax, fUpdateLevel, fUseZeros, fVerbose ); 00121 pManRst->pNtk = pNtk; 00122 // start the cut manager 00123 clk = clock(); 00124 pManCut = Abc_NtkStartCutManForRestruct( pNtk, nCutMax, fMulti ); 00125 pManRst->timeCut += clock() - clk; 00126 // pNtk->pManCut = pManCut; 00127 00128 // resynthesize each node once 00129 nNodes = Abc_NtkObjNumMax(pNtk); 00130 pProgress = Extra_ProgressBarStart( stdout, nNodes ); 00131 Abc_NtkForEachNode( pNtk, pNode, i ) 00132 { 00133 Extra_ProgressBarUpdate( pProgress, i, NULL ); 00134 // skip the constant node 00135 // if ( Abc_NodeIsConst(pNode) ) 00136 // continue; 00137 // skip persistant nodes 00138 if ( Abc_NodeIsPersistant(pNode) ) 00139 continue; 00140 // skip the node if it is inside the tree 00141 // if ( Abc_ObjFanoutNum(pNode) < 2 ) 00142 // continue; 00143 // skip the nodes with too many fanouts 00144 if ( Abc_ObjFanoutNum(pNode) > 1000 ) 00145 continue; 00146 // stop if all nodes have been tried once 00147 if ( i >= nNodes ) 00148 break; 00149 // get the cuts for the given node 00150 clk = clock(); 00151 pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti, 0 ); 00152 pManRst->timeCut += clock() - clk; 00153 00154 // perform restructuring 00155 clk = clock(); 00156 if ( fResub ) 00157 pGraph = Abc_NodeResubstitute( pManRst, pNode, pCutList ); 00158 else 00159 pGraph = Abc_NodeRestructure( pManRst, pNode, pCutList ); 00160 pManRst->timeRes += clock() - clk; 00161 if ( pGraph == NULL ) 00162 continue; 00163 00164 // acceptable replacement found, update the graph 00165 clk = clock(); 00166 Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, pManRst->nLastGain ); 00167 pManRst->timeNtk += clock() - clk; 00168 Dec_GraphFree( pGraph ); 00169 } 00170 Extra_ProgressBarStop( pProgress ); 00171 pManRst->timeTotal = clock() - clkStart; 00172 00173 // print statistics of the manager 00174 // if ( fVerbose ) 00175 Abc_NtkManRstPrintStats( pManRst ); 00176 // delete the managers 00177 Cut_ManStop( pManCut ); 00178 Abc_NtkManRstStop( pManRst ); 00179 // put the nodes into the DFS order and reassign their IDs 00180 Abc_NtkReassignIds( pNtk ); 00181 // Abc_AigCheckFaninOrder( pNtk->pManFunc ); 00182 // fix the levels 00183 if ( fUpdateLevel ) 00184 Abc_NtkStopReverseLevels( pNtk ); 00185 else 00186 Abc_NtkLevel( pNtk ); 00187 // check 00188 if ( !Abc_NtkCheck( pNtk ) ) 00189 { 00190 printf( "Abc_NtkRefactor: The network check has failed.\n" ); 00191 return 0; 00192 } 00193 return 1; 00194 }
Function*************************************************************
Synopsis [Starts the cut manager for rewriting.]
Description []
SideEffects []
SeeAlso []
Definition at line 955 of file abcRestruct.c.
00956 { 00957 static Cut_Params_t Params, * pParams = &Params; 00958 Cut_Man_t * pManCut; 00959 Abc_Obj_t * pObj; 00960 int i; 00961 // start the cut manager 00962 memset( pParams, 0, sizeof(Cut_Params_t) ); 00963 pParams->nVarsMax = nCutMax; // the max cut size ("k" of the k-feasible cuts) 00964 pParams->nKeepMax = 250; // the max number of cuts kept at a node 00965 pParams->fTruth = 0; // compute truth tables 00966 pParams->fFilter = 1; // filter dominated cuts 00967 pParams->fSeq = 0; // compute sequential cuts 00968 pParams->fDrop = 0; // drop cuts on the fly 00969 pParams->fDag = fDag; // compute DAG cuts 00970 pParams->fTree = 0; // compute tree cuts 00971 pParams->fVerbose = 0; // the verbosiness flag 00972 pParams->nIdsMax = Abc_NtkObjNumMax( pNtk ); 00973 pManCut = Cut_ManStart( pParams ); 00974 if ( pParams->fDrop ) 00975 Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) ); 00976 // set cuts for PIs 00977 Abc_NtkForEachCi( pNtk, pObj, i ) 00978 if ( Abc_ObjFanoutNum(pObj) > 0 ) 00979 Cut_NodeSetTriv( pManCut, pObj->Id ); 00980 return pManCut; 00981 }
void Abc_RestructNodeDivisors | ( | Abc_ManRst_t * | p, | |
Abc_Obj_t * | pRoot, | |||
int | nNodesSaved | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 207 of file abcRestruct.c.
00208 { 00209 Abc_Obj_t * pNode, * pFanout;//, * pFanin; 00210 int i, k; 00211 // start with the leaves 00212 Vec_PtrClear( p->vDecs ); 00213 Vec_PtrForEachEntry( p->vLeaves, pNode, i ) 00214 { 00215 Vec_PtrPush( p->vDecs, pNode ); 00216 assert( pNode->fMarkC == 0 ); 00217 pNode->fMarkC = 1; 00218 } 00219 // explore the fanouts 00220 Vec_PtrForEachEntry( p->vDecs, pNode, i ) 00221 { 00222 // if the fanout has both fanins in the set, add it 00223 Abc_ObjForEachFanout( pNode, pFanout, k ) 00224 { 00225 if ( pFanout->fMarkC || Abc_ObjIsPo(pFanout) ) 00226 continue; 00227 if ( Abc_ObjFanin0(pFanout)->fMarkC && Abc_ObjFanin1(pFanout)->fMarkC ) 00228 { 00229 Vec_PtrPush( p->vDecs, pFanout ); 00230 pFanout->fMarkC = 1; 00231 } 00232 } 00233 } 00234 // unmark the nodes 00235 Vec_PtrForEachEntry( p->vDecs, pNode, i ) 00236 pNode->fMarkC = 0; 00237 /* 00238 // print the nodes 00239 Vec_PtrForEachEntryStart( p->vDecs, pNode, i, Vec_PtrSize(p->vLeaves) ) 00240 { 00241 printf( "%2d %s = ", i, Abc_NodeIsTravIdCurrent(pNode)? "*" : " " ); 00242 // find the first fanin 00243 Vec_PtrForEachEntry( p->vDecs, pFanin, k ) 00244 if ( Abc_ObjFanin0(pNode) == pFanin ) 00245 break; 00246 if ( k < Vec_PtrSize(p->vLeaves) ) 00247 printf( "%c", 'a' + k ); 00248 else 00249 printf( "%d", k ); 00250 printf( "%s ", Abc_ObjFaninC0(pNode)? "\'" : "" ); 00251 // find the second fanin 00252 Vec_PtrForEachEntry( p->vDecs, pFanin, k ) 00253 if ( Abc_ObjFanin1(pNode) == pFanin ) 00254 break; 00255 if ( k < Vec_PtrSize(p->vLeaves) ) 00256 printf( "%c", 'a' + k ); 00257 else 00258 printf( "%d", k ); 00259 printf( "%s ", Abc_ObjFaninC1(pNode)? "\'" : "" ); 00260 printf( "\n" ); 00261 } 00262 */ 00263 printf( "%d\n", Vec_PtrSize(p->vDecs)-nNodesSaved-Vec_PtrSize(p->vLeaves) ); 00264 }