#include "ivy.h"
#include "deco.h"
#include "rwt.h"
Go to the source code of this file.
Functions | |
static int | Ivy_NodeRewriteSeq (Ivy_Man_t *pMan, Rwt_Man_t *p, Ivy_Obj_t *pNode, int fUseZeroCost) |
static void | Ivy_GraphPrepare (Dec_Graph_t *pGraph, Ivy_Cut_t *pCut, Vec_Ptr_t *vFanins, char *pPerm) |
static unsigned | Ivy_CutGetTruth (Ivy_Man_t *p, Ivy_Obj_t *pObj, int *pNums, int nNums) |
static Dec_Graph_t * | Rwt_CutEvaluateSeq (Ivy_Man_t *pMan, Rwt_Man_t *p, Ivy_Obj_t *pRoot, Ivy_Cut_t *pCut, char *pPerm, Vec_Ptr_t *vFaninsCur, int nNodesSaved, int *pGainBest, unsigned uTruth) |
static int | Ivy_GraphToNetworkSeqCountSeq (Ivy_Man_t *p, Ivy_Obj_t *pRoot, Dec_Graph_t *pGraph, int NodeMax) |
static Ivy_Obj_t * | Ivy_GraphToNetworkSeq (Ivy_Man_t *p, Dec_Graph_t *pGraph) |
static void | Ivy_GraphUpdateNetworkSeq (Ivy_Man_t *p, Ivy_Obj_t *pRoot, Dec_Graph_t *pGraph, int nGain) |
static Ivy_Store_t * | Ivy_CutComputeForNode (Ivy_Man_t *p, Ivy_Obj_t *pObj, int nLeaves) |
static int | Ivy_CutHashValue (int NodeId) |
int | Ivy_ManRewriteSeq (Ivy_Man_t *p, int fUseZeroCost, int fVerbose) |
unsigned | Ivy_CutGetTruth_rec (Ivy_Man_t *p, int Leaf, int *pNums, int nNums) |
static int | Ivy_CutPrescreen (Ivy_Cut_t *pCut, int Id0, int Id1) |
static int | Ivy_CutDeriveNew2 (Ivy_Cut_t *pCut, Ivy_Cut_t *pCutNew, int IdOld, int IdNew0, int IdNew1) |
static int | Ivy_CutDeriveNew (Ivy_Cut_t *pCut, Ivy_Cut_t *pCutNew, int IdOld, int IdNew0, int IdNew1) |
static unsigned | Ivy_NodeCutHash (Ivy_Cut_t *pCut) |
static int | Ivy_CutDeriveNew3 (Ivy_Cut_t *pCut, Ivy_Cut_t *pCutNew, int IdOld, int IdNew0, int IdNew1) |
static int | Ivy_CutCheckDominance (Ivy_Cut_t *pDom, Ivy_Cut_t *pCut) |
int | Ivy_CutFindOrAddFilter (Ivy_Store_t *pCutStore, Ivy_Cut_t *pCutNew) |
void | Ivy_CutCompactAll (Ivy_Store_t *pCutStore) |
void | Ivy_CutPrintForNode (Ivy_Cut_t *pCut) |
void | Ivy_CutPrintForNodes (Ivy_Store_t *pCutStore) |
static int | Ivy_CutReadLeaf (Ivy_Obj_t *pFanin) |
void | Ivy_CutComputeAll (Ivy_Man_t *p, int nInputs) |
Function*************************************************************
Synopsis [Returns 1 if pDom is contained in pCut.]
Description []
SideEffects []
SeeAlso []
Definition at line 839 of file ivySeq.c.
00840 { 00841 int i, k; 00842 for ( i = 0; i < pDom->nSize; i++ ) 00843 { 00844 assert( i==0 || pDom->pArray[i-1] < pDom->pArray[i] ); 00845 for ( k = 0; k < pCut->nSize; k++ ) 00846 if ( pDom->pArray[i] == pCut->pArray[k] ) 00847 break; 00848 if ( k == pCut->nSize ) // node i in pDom is not contained in pCut 00849 return 0; 00850 } 00851 // every node in pDom is contained in pCut 00852 return 1; 00853 }
void Ivy_CutCompactAll | ( | Ivy_Store_t * | pCutStore | ) |
Function*************************************************************
Synopsis [Compresses the cut representation.]
Description []
SideEffects []
SeeAlso []
Definition at line 929 of file ivySeq.c.
00930 { 00931 Ivy_Cut_t * pCut; 00932 int i, k; 00933 pCutStore->nCutsM = 0; 00934 for ( i = k = 0; i < pCutStore->nCuts; i++ ) 00935 { 00936 pCut = pCutStore->pCuts + i; 00937 if ( pCut->nSize == 0 ) 00938 continue; 00939 if ( pCut->nSize < pCut->nSizeMax ) 00940 pCutStore->nCutsM++; 00941 pCutStore->pCuts[k++] = *pCut; 00942 } 00943 pCutStore->nCuts = k; 00944 }
void Ivy_CutComputeAll | ( | Ivy_Man_t * | p, | |
int | nInputs | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 1102 of file ivySeq.c.
01103 { 01104 Ivy_Store_t * pStore; 01105 Ivy_Obj_t * pObj; 01106 int i, nCutsTotal, nCutsTotalM, nNodeTotal, nNodeOver; 01107 int clk = clock(); 01108 if ( nInputs > IVY_CUT_INPUT ) 01109 { 01110 printf( "Cannot compute cuts for more than %d inputs.\n", IVY_CUT_INPUT ); 01111 return; 01112 } 01113 nNodeTotal = nNodeOver = 0; 01114 nCutsTotal = nCutsTotalM = -Ivy_ManNodeNum(p); 01115 Ivy_ManForEachObj( p, pObj, i ) 01116 { 01117 if ( !Ivy_ObjIsNode(pObj) ) 01118 continue; 01119 pStore = Ivy_CutComputeForNode( p, pObj, nInputs ); 01120 nCutsTotal += pStore->nCuts; 01121 nCutsTotalM += pStore->nCutsM; 01122 nNodeOver += pStore->fSatur; 01123 nNodeTotal++; 01124 } 01125 printf( "All = %6d. Minus = %6d. Triv = %6d. Node = %6d. Satur = %6d. ", 01126 nCutsTotal, nCutsTotalM, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver ); 01127 PRT( "Time", clock() - clk ); 01128 }
Ivy_Store_t * Ivy_CutComputeForNode | ( | Ivy_Man_t * | p, | |
Ivy_Obj_t * | pObj, | |||
int | nLeaves | |||
) | [static] |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 1020 of file ivySeq.c.
01021 { 01022 static Ivy_Store_t CutStore, * pCutStore = &CutStore; 01023 Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut; 01024 Ivy_Man_t * pMan = p; 01025 Ivy_Obj_t * pLeaf; 01026 int i, k, Temp, nLats, iLeaf0, iLeaf1; 01027 01028 assert( nLeaves <= IVY_CUT_INPUT ); 01029 01030 // start the structure 01031 pCutStore->nCuts = 0; 01032 pCutStore->nCutsMax = IVY_CUT_LIMIT; 01033 // start the trivial cut 01034 pCutNew->uHash = 0; 01035 pCutNew->nSize = 1; 01036 pCutNew->nSizeMax = nLeaves; 01037 pCutNew->pArray[0] = Ivy_LeafCreate( pObj->Id, 0 ); 01038 pCutNew->uHash = Ivy_CutHashValue( pCutNew->pArray[0] ); 01039 // add the trivial cut 01040 pCutStore->pCuts[pCutStore->nCuts++] = *pCutNew; 01041 assert( pCutStore->nCuts == 1 ); 01042 01043 // explore the cuts 01044 for ( i = 0; i < pCutStore->nCuts; i++ ) 01045 { 01046 // expand this cut 01047 pCut = pCutStore->pCuts + i; 01048 if ( pCut->nSize == 0 ) 01049 continue; 01050 for ( k = 0; k < pCut->nSize; k++ ) 01051 { 01052 pLeaf = Ivy_ManObj( p, Ivy_LeafId(pCut->pArray[k]) ); 01053 if ( Ivy_ObjIsCi(pLeaf) || Ivy_ObjIsConst1(pLeaf) ) 01054 continue; 01055 assert( Ivy_ObjIsNode(pLeaf) ); 01056 nLats = Ivy_LeafLat(pCut->pArray[k]); 01057 01058 // get the fanins fanins 01059 iLeaf0 = Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) ); 01060 iLeaf1 = Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) ); 01061 assert( nLats + Ivy_LeafLat(iLeaf0) < IVY_LEAF_MASK && nLats + Ivy_LeafLat(iLeaf1) < IVY_LEAF_MASK ); 01062 iLeaf0 = nLats + iLeaf0; 01063 iLeaf1 = nLats + iLeaf1; 01064 if ( !Ivy_CutPrescreen( pCut, iLeaf0, iLeaf1 ) ) 01065 continue; 01066 // the given cut exist 01067 if ( iLeaf0 > iLeaf1 ) 01068 Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp; 01069 // create the new cut 01070 if ( !Ivy_CutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ) ) 01071 continue; 01072 // add the cut 01073 Ivy_CutFindOrAddFilter( pCutStore, pCutNew ); 01074 if ( pCutStore->nCuts == IVY_CUT_LIMIT ) 01075 break; 01076 } 01077 if ( pCutStore->nCuts == IVY_CUT_LIMIT ) 01078 break; 01079 } 01080 if ( pCutStore->nCuts == IVY_CUT_LIMIT ) 01081 pCutStore->fSatur = 1; 01082 else 01083 pCutStore->fSatur = 0; 01084 // printf( "%d ", pCutStore->nCuts ); 01085 Ivy_CutCompactAll( pCutStore ); 01086 // printf( "%d \n", pCutStore->nCuts ); 01087 // Ivy_CutPrintForNodes( pCutStore ); 01088 return pCutStore; 01089 }
static int Ivy_CutDeriveNew | ( | Ivy_Cut_t * | pCut, | |
Ivy_Cut_t * | pCutNew, | |||
int | IdOld, | |||
int | IdNew0, | |||
int | IdNew1 | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Derives new cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 715 of file ivySeq.c.
00716 { 00717 unsigned uHash = 0; 00718 int i, k; 00719 assert( pCut->nSize > 0 ); 00720 assert( IdNew0 < IdNew1 ); 00721 for ( i = k = 0; i < pCut->nSize; i++ ) 00722 { 00723 if ( pCut->pArray[i] == IdOld ) 00724 continue; 00725 if ( IdNew0 <= pCut->pArray[i] ) 00726 { 00727 if ( IdNew0 < pCut->pArray[i] ) 00728 { 00729 pCutNew->pArray[ k++ ] = IdNew0; 00730 uHash |= Ivy_CutHashValue( IdNew0 ); 00731 } 00732 IdNew0 = 0x7FFFFFFF; 00733 } 00734 if ( IdNew1 <= pCut->pArray[i] ) 00735 { 00736 if ( IdNew1 < pCut->pArray[i] ) 00737 { 00738 pCutNew->pArray[ k++ ] = IdNew1; 00739 uHash |= Ivy_CutHashValue( IdNew1 ); 00740 } 00741 IdNew1 = 0x7FFFFFFF; 00742 } 00743 pCutNew->pArray[ k++ ] = pCut->pArray[i]; 00744 uHash |= Ivy_CutHashValue( pCut->pArray[i] ); 00745 } 00746 if ( IdNew0 < 0x7FFFFFFF ) 00747 { 00748 pCutNew->pArray[ k++ ] = IdNew0; 00749 uHash |= Ivy_CutHashValue( IdNew0 ); 00750 } 00751 if ( IdNew1 < 0x7FFFFFFF ) 00752 { 00753 pCutNew->pArray[ k++ ] = IdNew1; 00754 uHash |= Ivy_CutHashValue( IdNew1 ); 00755 } 00756 pCutNew->nSize = k; 00757 pCutNew->uHash = uHash; 00758 assert( pCutNew->nSize <= pCut->nSizeMax ); 00759 // for ( i = 1; i < pCutNew->nSize; i++ ) 00760 // assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); 00761 return 1; 00762 }
static int Ivy_CutDeriveNew2 | ( | Ivy_Cut_t * | pCut, | |
Ivy_Cut_t * | pCutNew, | |||
int | IdOld, | |||
int | IdNew0, | |||
int | IdNew1 | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Derives new cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 639 of file ivySeq.c.
00640 { 00641 unsigned uHash = 0; 00642 int i, k; 00643 assert( pCut->nSize > 0 ); 00644 assert( IdNew0 < IdNew1 ); 00645 for ( i = k = 0; i < pCut->nSize; i++ ) 00646 { 00647 if ( pCut->pArray[i] == IdOld ) 00648 continue; 00649 if ( IdNew0 >= 0 ) 00650 { 00651 if ( IdNew0 <= pCut->pArray[i] ) 00652 { 00653 if ( IdNew0 < pCut->pArray[i] ) 00654 { 00655 if ( k == pCut->nSizeMax ) 00656 return 0; 00657 pCutNew->pArray[ k++ ] = IdNew0; 00658 uHash |= Ivy_CutHashValue( IdNew0 ); 00659 } 00660 IdNew0 = -1; 00661 } 00662 } 00663 if ( IdNew1 >= 0 ) 00664 { 00665 if ( IdNew1 <= pCut->pArray[i] ) 00666 { 00667 if ( IdNew1 < pCut->pArray[i] ) 00668 { 00669 if ( k == pCut->nSizeMax ) 00670 return 0; 00671 pCutNew->pArray[ k++ ] = IdNew1; 00672 uHash |= Ivy_CutHashValue( IdNew1 ); 00673 } 00674 IdNew1 = -1; 00675 } 00676 } 00677 if ( k == pCut->nSizeMax ) 00678 return 0; 00679 pCutNew->pArray[ k++ ] = pCut->pArray[i]; 00680 uHash |= Ivy_CutHashValue( pCut->pArray[i] ); 00681 } 00682 if ( IdNew0 >= 0 ) 00683 { 00684 if ( k == pCut->nSizeMax ) 00685 return 0; 00686 pCutNew->pArray[ k++ ] = IdNew0; 00687 uHash |= Ivy_CutHashValue( IdNew0 ); 00688 } 00689 if ( IdNew1 >= 0 ) 00690 { 00691 if ( k == pCut->nSizeMax ) 00692 return 0; 00693 pCutNew->pArray[ k++ ] = IdNew1; 00694 uHash |= Ivy_CutHashValue( IdNew1 ); 00695 } 00696 pCutNew->nSize = k; 00697 pCutNew->uHash = uHash; 00698 assert( pCutNew->nSize <= pCut->nSizeMax ); 00699 for ( i = 1; i < pCutNew->nSize; i++ ) 00700 assert( pCutNew->pArray[i-1] < pCutNew->pArray[i] ); 00701 return 1; 00702 }
static int Ivy_CutDeriveNew3 | ( | Ivy_Cut_t * | pCut, | |
Ivy_Cut_t * | pCutNew, | |||
int | IdOld, | |||
int | IdNew0, | |||
int | IdNew1 | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Derives new cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 795 of file ivySeq.c.
00796 { 00797 int i, k; 00798 assert( pCut->nSize > 0 ); 00799 assert( IdNew0 < IdNew1 ); 00800 for ( i = k = 0; i < pCut->nSize; i++ ) 00801 { 00802 if ( pCut->pArray[i] == IdOld ) 00803 continue; 00804 if ( IdNew0 <= pCut->pArray[i] ) 00805 { 00806 if ( IdNew0 < pCut->pArray[i] ) 00807 pCutNew->pArray[ k++ ] = IdNew0; 00808 IdNew0 = 0x7FFFFFFF; 00809 } 00810 if ( IdNew1 <= pCut->pArray[i] ) 00811 { 00812 if ( IdNew1 < pCut->pArray[i] ) 00813 pCutNew->pArray[ k++ ] = IdNew1; 00814 IdNew1 = 0x7FFFFFFF; 00815 } 00816 pCutNew->pArray[ k++ ] = pCut->pArray[i]; 00817 } 00818 if ( IdNew0 < 0x7FFFFFFF ) 00819 pCutNew->pArray[ k++ ] = IdNew0; 00820 if ( IdNew1 < 0x7FFFFFFF ) 00821 pCutNew->pArray[ k++ ] = IdNew1; 00822 pCutNew->nSize = k; 00823 assert( pCutNew->nSize <= pCut->nSizeMax ); 00824 Ivy_NodeCutHash( pCutNew ); 00825 return 1; 00826 }
int Ivy_CutFindOrAddFilter | ( | Ivy_Store_t * | pCutStore, | |
Ivy_Cut_t * | pCutNew | |||
) |
Function*************************************************************
Synopsis [Check if the cut exists.]
Description [Returns 1 if the cut exists.]
SideEffects []
SeeAlso []
Definition at line 866 of file ivySeq.c.
00867 { 00868 Ivy_Cut_t * pCut; 00869 int i, k; 00870 assert( pCutNew->uHash ); 00871 // try to find the cut 00872 for ( i = 0; i < pCutStore->nCuts; i++ ) 00873 { 00874 pCut = pCutStore->pCuts + i; 00875 if ( pCut->nSize == 0 ) 00876 continue; 00877 if ( pCut->nSize == pCutNew->nSize ) 00878 { 00879 if ( pCut->uHash == pCutNew->uHash ) 00880 { 00881 for ( k = 0; k < pCutNew->nSize; k++ ) 00882 if ( pCut->pArray[k] != pCutNew->pArray[k] ) 00883 break; 00884 if ( k == pCutNew->nSize ) 00885 return 1; 00886 } 00887 continue; 00888 } 00889 if ( pCut->nSize < pCutNew->nSize ) 00890 { 00891 // skip the non-contained cuts 00892 if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash ) 00893 continue; 00894 // check containment seriously 00895 if ( Ivy_CutCheckDominance( pCut, pCutNew ) ) 00896 return 1; 00897 continue; 00898 } 00899 // check potential containment of other cut 00900 00901 // skip the non-contained cuts 00902 if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash ) 00903 continue; 00904 // check containment seriously 00905 if ( Ivy_CutCheckDominance( pCutNew, pCut ) ) 00906 { 00907 // remove the current cut 00908 pCut->nSize = 0; 00909 } 00910 } 00911 assert( pCutStore->nCuts < pCutStore->nCutsMax ); 00912 // add the cut 00913 pCut = pCutStore->pCuts + pCutStore->nCuts++; 00914 *pCut = *pCutNew; 00915 return 0; 00916 }
Function*************************************************************
Synopsis [Computes the truth table.]
Description []
SideEffects []
SeeAlso []
Definition at line 595 of file ivySeq.c.
00596 { 00597 assert( Ivy_ObjIsNode(pObj) ); 00598 assert( nNums < 6 ); 00599 return Ivy_CutGetTruth_rec( p, Ivy_LeafCreate(pObj->Id, 0), pNums, nNums ); 00600 }
unsigned Ivy_CutGetTruth_rec | ( | Ivy_Man_t * | p, | |
int | Leaf, | |||
int * | pNums, | |||
int | nNums | |||
) |
Function*************************************************************
Synopsis [Computes the truth table.]
Description []
SideEffects []
SeeAlso []
Definition at line 553 of file ivySeq.c.
00554 { 00555 static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; 00556 unsigned uTruth0, uTruth1; 00557 Ivy_Obj_t * pObj; 00558 int i; 00559 for ( i = 0; i < nNums; i++ ) 00560 if ( Leaf == pNums[i] ) 00561 return uMasks[i]; 00562 pObj = Ivy_ManObj( p, Ivy_LeafId(Leaf) ); 00563 if ( Ivy_ObjIsLatch(pObj) ) 00564 { 00565 assert( !Ivy_ObjFaninC0(pObj) ); 00566 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) + 1 ); 00567 return Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); 00568 } 00569 assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); 00570 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) ); 00571 uTruth0 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); 00572 if ( Ivy_ObjFaninC0(pObj) ) 00573 uTruth0 = ~uTruth0; 00574 if ( Ivy_ObjIsBuf(pObj) ) 00575 return uTruth0; 00576 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pObj), Ivy_LeafLat(Leaf) ); 00577 uTruth1 = Ivy_CutGetTruth_rec( p, Leaf, pNums, nNums ); 00578 if ( Ivy_ObjFaninC1(pObj) ) 00579 uTruth1 = ~uTruth1; 00580 return uTruth0 & uTruth1; 00581 }
static int Ivy_CutHashValue | ( | int | NodeId | ) | [inline, static] |
static int Ivy_CutPrescreen | ( | Ivy_Cut_t * | pCut, | |
int | Id0, | |||
int | Id1 | |||
) | [inline, static] |
Function*************************************************************
Synopsis [Returns 1 if the cut can be constructed; 0 otherwise.]
Description []
SideEffects []
SeeAlso []
void Ivy_CutPrintForNode | ( | Ivy_Cut_t * | pCut | ) |
Function*************************************************************
Synopsis [Print the cut.]
Description []
SideEffects []
SeeAlso []
void Ivy_CutPrintForNodes | ( | Ivy_Store_t * | pCutStore | ) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 978 of file ivySeq.c.
00979 { 00980 int i; 00981 printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] ); 00982 for ( i = 0; i < pCutStore->nCuts; i++ ) 00983 Ivy_CutPrintForNode( pCutStore->pCuts + i ); 00984 }
static int Ivy_CutReadLeaf | ( | Ivy_Obj_t * | pFanin | ) | [inline, static] |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 997 of file ivySeq.c.
00998 { 00999 int nLats, iLeaf; 01000 assert( !Ivy_IsComplement(pFanin) ); 01001 if ( !Ivy_ObjIsLatch(pFanin) ) 01002 return Ivy_LeafCreate( pFanin->Id, 0 ); 01003 iLeaf = Ivy_CutReadLeaf(Ivy_ObjFanin0(pFanin)); 01004 nLats = Ivy_LeafLat(iLeaf); 01005 assert( nLats < IVY_LEAF_MASK ); 01006 return 1 + iLeaf; 01007 }
void Ivy_GraphPrepare | ( | Dec_Graph_t * | pGraph, | |
Ivy_Cut_t * | pCut, | |||
Vec_Ptr_t * | vFanins, | |||
char * | pPerm | |||
) | [static] |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 357 of file ivySeq.c.
00358 { 00359 Dec_Node_t * pNode, * pNode0, * pNode1; 00360 int i; 00361 assert( Dec_GraphLeaveNum(pGraph) == pCut->nSize ); 00362 assert( Vec_PtrSize(vFanins) == pCut->nSize ); 00363 // label the leaves with latch numbers 00364 Dec_GraphForEachLeaf( pGraph, pNode, i ) 00365 { 00366 pNode->pFunc = Vec_PtrEntry( vFanins, i ); 00367 pNode->nLat2 = Ivy_LeafLat( pCut->pArray[pPerm[i]] ); 00368 } 00369 // propagate latches through the nodes 00370 Dec_GraphForEachNode( pGraph, pNode, i ) 00371 { 00372 // get the children of this node 00373 pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); 00374 pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); 00375 // distribute the latches 00376 pNode->nLat2 = IVY_MIN( pNode0->nLat2, pNode1->nLat2 ); 00377 pNode->nLat0 = pNode0->nLat2 - pNode->nLat2; 00378 pNode->nLat1 = pNode1->nLat2 - pNode->nLat2; 00379 } 00380 }
Ivy_Obj_t * Ivy_GraphToNetworkSeq | ( | Ivy_Man_t * | p, | |
Dec_Graph_t * | pGraph | |||
) | [static] |
Function*************************************************************
Synopsis [Transforms the decomposition graph into the AIG.]
Description [AIG nodes for the fanins should be assigned to pNode->pFunc of the leaves of the graph before calling this procedure.]
SideEffects []
SeeAlso []
Definition at line 470 of file ivySeq.c.
00471 { 00472 Ivy_Obj_t * pAnd0, * pAnd1; 00473 Dec_Node_t * pNode; 00474 int i, k; 00475 // check for constant function 00476 if ( Dec_GraphIsConst(pGraph) ) 00477 return Ivy_NotCond( Ivy_ManConst1(p), Dec_GraphIsComplement(pGraph) ); 00478 // check for a literal 00479 if ( Dec_GraphIsVar(pGraph) ) 00480 { 00481 // get the variable node 00482 pNode = Dec_GraphVar(pGraph); 00483 // add the remaining latches 00484 for ( k = 0; k < (int)pNode->nLat2; k++ ) 00485 pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); 00486 return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); 00487 } 00488 // build the AIG nodes corresponding to the AND gates of the graph 00489 Dec_GraphForEachNode( pGraph, pNode, i ) 00490 { 00491 pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl ); 00492 pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl ); 00493 // add the latches 00494 for ( k = 0; k < (int)pNode->nLat0; k++ ) 00495 pAnd0 = Ivy_Latch( p, pAnd0, IVY_INIT_DC ); 00496 for ( k = 0; k < (int)pNode->nLat1; k++ ) 00497 pAnd1 = Ivy_Latch( p, pAnd1, IVY_INIT_DC ); 00498 // create the node 00499 pNode->pFunc = Ivy_And( p, pAnd0, pAnd1 ); 00500 } 00501 // add the remaining latches 00502 for ( k = 0; k < (int)pNode->nLat2; k++ ) 00503 pNode->pFunc = Ivy_Latch( p, pNode->pFunc, IVY_INIT_DC ); 00504 // complement the result if necessary 00505 return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); 00506 }
int Ivy_GraphToNetworkSeqCountSeq | ( | Ivy_Man_t * | p, | |
Ivy_Obj_t * | pRoot, | |||
Dec_Graph_t * | pGraph, | |||
int | NodeMax | |||
) | [static] |
Function*************************************************************
Synopsis [Counts the number of new nodes added when using this graph.]
Description [AIG nodes for the fanins should be assigned to pNode->pFunc of the leaves of the graph before calling this procedure. Returns -1 if the number of nodes and levels exceeded the given limit or the number of levels exceeded the maximum allowed level.]
SideEffects []
SeeAlso []
Definition at line 396 of file ivySeq.c.
00397 { 00398 Dec_Node_t * pNode, * pNode0, * pNode1; 00399 Ivy_Obj_t * pAnd, * pAnd0, * pAnd1; 00400 int i, k, Counter, fCompl; 00401 // check for constant function or a literal 00402 if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) ) 00403 return 0; 00404 // compute the AIG size after adding the internal nodes 00405 Counter = 0; 00406 Dec_GraphForEachNode( pGraph, pNode, i ) 00407 { 00408 // get the children of this node 00409 pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); 00410 pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); 00411 // get the AIG nodes corresponding to the children 00412 pAnd0 = pNode0->pFunc; 00413 pAnd1 = pNode1->pFunc; 00414 // skip the latches 00415 for ( k = 0; pAnd0 && k < (int)pNode->nLat0; k++ ) 00416 { 00417 fCompl = Ivy_IsComplement(pAnd0); 00418 pAnd0 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd0), NULL, IVY_LATCH, IVY_INIT_DC) ); 00419 if ( pAnd0 ) 00420 pAnd0 = Ivy_NotCond( pAnd0, fCompl ); 00421 } 00422 for ( k = 0; pAnd1 && k < (int)pNode->nLat1; k++ ) 00423 { 00424 fCompl = Ivy_IsComplement(pAnd1); 00425 pAnd1 = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, Ivy_Regular(pAnd1), NULL, IVY_LATCH, IVY_INIT_DC) ); 00426 if ( pAnd1 ) 00427 pAnd1 = Ivy_NotCond( pAnd1, fCompl ); 00428 } 00429 // get the new node 00430 if ( pAnd0 && pAnd1 ) 00431 { 00432 // if they are both present, find the resulting node 00433 pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl ); 00434 pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl ); 00435 assert( !Ivy_ObjIsLatch(Ivy_Regular(pAnd0)) || !Ivy_ObjIsLatch(Ivy_Regular(pAnd1)) ); 00436 if ( Ivy_Regular(pAnd0) == Ivy_Regular(pAnd1) || Ivy_ObjIsConst1(Ivy_Regular(pAnd0)) || Ivy_ObjIsConst1(Ivy_Regular(pAnd1)) ) 00437 pAnd = Ivy_And( p, pAnd0, pAnd1 ); 00438 else 00439 pAnd = Ivy_TableLookup( p, Ivy_ObjCreateGhost(p, pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) ); 00440 // return -1 if the node is the same as the original root 00441 if ( Ivy_Regular(pAnd) == pRoot ) 00442 return -1; 00443 } 00444 else 00445 pAnd = NULL; 00446 // count the number of added nodes 00447 if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(p, Ivy_Regular(pAnd)) ) 00448 { 00449 if ( ++Counter > NodeMax ) 00450 return -1; 00451 } 00452 pNode->pFunc = pAnd; 00453 } 00454 return Counter; 00455 }
void Ivy_GraphUpdateNetworkSeq | ( | Ivy_Man_t * | p, | |
Ivy_Obj_t * | pRoot, | |||
Dec_Graph_t * | pGraph, | |||
int | nGain | |||
) | [static] |
Function*************************************************************
Synopsis [Replaces MFFC of the node by the new factored form.]
Description []
SideEffects []
SeeAlso []
Definition at line 519 of file ivySeq.c.
00520 { 00521 Ivy_Obj_t * pRootNew; 00522 int nNodesNew, nNodesOld; 00523 nNodesOld = Ivy_ManNodeNum(p); 00524 // create the new structure of nodes 00525 pRootNew = Ivy_GraphToNetworkSeq( p, pGraph ); 00526 Ivy_ObjReplace( p, pRoot, pRootNew, 1, 0, 0 ); 00527 // compare the gains 00528 nNodesNew = Ivy_ManNodeNum(p); 00529 assert( nGain <= nNodesOld - nNodesNew ); 00530 // propagate the buffer 00531 Ivy_ManPropagateBuffers( p, 0 ); 00532 }
int Ivy_ManRewriteSeq | ( | Ivy_Man_t * | p, | |
int | fUseZeroCost, | |||
int | fVerbose | |||
) |
FUNCTION DEFINITIONS ///Function*************************************************************
Synopsis [Performs incremental rewriting of the AIG.]
Description []
SideEffects []
SeeAlso []
Definition at line 60 of file ivySeq.c.
00061 { 00062 Rwt_Man_t * pManRwt; 00063 Ivy_Obj_t * pNode; 00064 int i, nNodes, nGain; 00065 int clk, clkStart = clock(); 00066 00067 // set the DC latch values 00068 Ivy_ManForEachLatch( p, pNode, i ) 00069 pNode->Init = IVY_INIT_DC; 00070 // start the rewriting manager 00071 pManRwt = Rwt_ManStart( 0 ); 00072 p->pData = pManRwt; 00073 if ( pManRwt == NULL ) 00074 return 0; 00075 // create fanouts 00076 if ( p->fFanout == 0 ) 00077 Ivy_ManStartFanout( p ); 00078 // resynthesize each node once 00079 nNodes = Ivy_ManObjIdMax(p); 00080 Ivy_ManForEachNode( p, pNode, i ) 00081 { 00082 assert( !Ivy_ObjIsBuf(pNode) ); 00083 assert( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) ); 00084 assert( !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ); 00085 // fix the fanin buffer problem 00086 // Ivy_NodeFixBufferFanins( p, pNode ); 00087 // if ( Ivy_ObjIsBuf(pNode) ) 00088 // continue; 00089 // stop if all nodes have been tried once 00090 if ( i > nNodes ) 00091 break; 00092 // for each cut, try to resynthesize it 00093 nGain = Ivy_NodeRewriteSeq( p, pManRwt, pNode, fUseZeroCost ); 00094 if ( nGain > 0 || nGain == 0 && fUseZeroCost ) 00095 { 00096 Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt); 00097 int fCompl = Rwt_ManReadCompl(pManRwt); 00098 // complement the FF if needed 00099 clk = clock(); 00100 if ( fCompl ) Dec_GraphComplement( pGraph ); 00101 Ivy_GraphUpdateNetworkSeq( p, pNode, pGraph, nGain ); 00102 if ( fCompl ) Dec_GraphComplement( pGraph ); 00103 Rwt_ManAddTimeUpdate( pManRwt, clock() - clk ); 00104 } 00105 } 00106 Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart ); 00107 // print stats 00108 if ( fVerbose ) 00109 Rwt_ManPrintStats( pManRwt ); 00110 // delete the managers 00111 Rwt_ManStop( pManRwt ); 00112 p->pData = NULL; 00113 // fix the levels 00114 Ivy_ManResetLevels( p ); 00115 // if ( Ivy_ManCheckFanoutNums(p) ) 00116 // printf( "Ivy_ManRewritePre(): The check has failed.\n" ); 00117 // check 00118 if ( !Ivy_ManCheck(p) ) 00119 printf( "Ivy_ManRewritePre(): The check has failed.\n" ); 00120 return 1; 00121 }
static unsigned Ivy_NodeCutHash | ( | Ivy_Cut_t * | pCut | ) | [inline, static] |
Function*************************************************************
Synopsis [Find the hash value of the cut.]
Description []
SideEffects []
SeeAlso []
int Ivy_NodeRewriteSeq | ( | Ivy_Man_t * | pMan, | |
Rwt_Man_t * | p, | |||
Ivy_Obj_t * | pNode, | |||
int | fUseZeroCost | |||
) | [static] |
CFile****************************************************************
FileName [ivySeq.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [And-Inverter Graph package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - May 11, 2006.]
Revision [
] DECLARATIONS ///
Function*************************************************************
Synopsis [Performs rewriting for one node.]
Description [This procedure considers all the cuts computed for the node and tries to rewrite each of them using the "forest" of different AIG structures precomputed and stored in the RWR manager. Determines the best rewriting and computes the gain in the number of AIG nodes in the final network. In the end, p->vFanins contains information about the best cut that can be used for rewriting, while p->pGraph gives the decomposition dag (represented using decomposition graph data structure). Returns gain in the number of nodes or -1 if node cannot be rewritten.]
SideEffects []
SeeAlso []
Definition at line 142 of file ivySeq.c.
00143 { 00144 int fVeryVerbose = 0; 00145 Dec_Graph_t * pGraph; 00146 Ivy_Store_t * pStore; 00147 Ivy_Cut_t * pCut; 00148 Ivy_Obj_t * pFanin;//, * pFanout; 00149 Vec_Ptr_t * vFanout; 00150 unsigned uPhase, uTruthBest, uTruth;//, nNewClauses; 00151 char * pPerm; 00152 int nNodesSaved, nNodesSaveCur; 00153 int i, c, GainCur, GainBest = -1; 00154 int clk, clk2;//, clk3; 00155 00156 p->nNodesConsidered++; 00157 // get the node's cuts 00158 clk = clock(); 00159 pStore = Ivy_CutComputeForNode( pMan, pNode, 5 ); 00160 p->timeCut += clock() - clk; 00161 00162 // go through the cuts 00163 clk = clock(); 00164 vFanout = Vec_PtrAlloc( 100 ); 00165 for ( c = 1; c < pStore->nCuts; c++ ) 00166 { 00167 pCut = pStore->pCuts + c; 00168 // consider only 4-input cuts 00169 if ( pCut->nSize != 4 ) 00170 continue; 00171 // skip the cuts with buffers 00172 for ( i = 0; i < (int)pCut->nSize; i++ ) 00173 if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, Ivy_LeafId(pCut->pArray[i])) ) ) 00174 break; 00175 if ( i != pCut->nSize ) 00176 { 00177 p->nCutsBad++; 00178 continue; 00179 } 00180 p->nCutsGood++; 00181 // get the fanin permutation 00182 clk2 = clock(); 00183 uTruth = 0xFFFF & Ivy_CutGetTruth( pMan, pNode, pCut->pArray, pCut->nSize ); // truth table 00184 p->timeTruth += clock() - clk2; 00185 pPerm = p->pPerms4[ p->pPerms[uTruth] ]; 00186 uPhase = p->pPhases[uTruth]; 00187 // collect fanins with the corresponding permutation/phase 00188 Vec_PtrClear( p->vFaninsCur ); 00189 Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 ); 00190 for ( i = 0; i < (int)pCut->nSize; i++ ) 00191 { 00192 pFanin = Ivy_ManObj( pMan, Ivy_LeafId( pCut->pArray[pPerm[i]] ) ); 00193 assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) || Ivy_ObjIsConst1(pFanin) ); 00194 pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) ); 00195 Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin ); 00196 } 00197 clk2 = clock(); 00198 // mark the fanin boundary 00199 Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) 00200 Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); 00201 // label MFFC with current ID 00202 Ivy_ManIncrementTravId( pMan ); 00203 nNodesSaved = Ivy_ObjMffcLabel( pMan, pNode ); 00204 // label fanouts with the current ID 00205 // Ivy_ObjForEachFanout( pMan, pNode, vFanout, pFanout, i ) 00206 // Ivy_ObjSetTravIdCurrent( pMan, pFanout ); 00207 // unmark the fanin boundary 00208 Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) 00209 Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); 00210 p->timeMffc += clock() - clk2; 00211 00212 // evaluate the cut 00213 clk2 = clock(); 00214 pGraph = Rwt_CutEvaluateSeq( pMan, p, pNode, pCut, pPerm, p->vFaninsCur, nNodesSaved, &GainCur, uTruth ); 00215 p->timeEval += clock() - clk2; 00216 00217 00218 // check if the cut is better than the current best one 00219 if ( pGraph != NULL && GainBest < GainCur ) 00220 { 00221 // save this form 00222 nNodesSaveCur = nNodesSaved; 00223 GainBest = GainCur; 00224 p->pGraph = pGraph; 00225 p->pCut = pCut; 00226 p->pPerm = pPerm; 00227 p->fCompl = ((uPhase & (1<<4)) > 0); 00228 uTruthBest = uTruth; 00229 // collect fanins in the 00230 Vec_PtrClear( p->vFanins ); 00231 Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) 00232 Vec_PtrPush( p->vFanins, pFanin ); 00233 } 00234 } 00235 Vec_PtrFree( vFanout ); 00236 p->timeRes += clock() - clk; 00237 00238 if ( GainBest == -1 ) 00239 return -1; 00240 /* 00241 { 00242 Ivy_Cut_t * pCut = p->pCut; 00243 printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) ); 00244 for ( i = 0; i < pCut->nSize; i++ ) 00245 printf( " %d(%d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) ); 00246 printf( " }\n" ); 00247 } 00248 */ 00249 00250 //clk3 = clock(); 00251 //nNewClauses = Ivy_CutTruthPrint( pMan, p->pCut, uTruth ); 00252 //timeInv += clock() - clk; 00253 00254 // nClauses += nNewClauses; 00255 // nMoves++; 00256 // if ( nNewClauses > 0 ) 00257 // nMovesS++; 00258 00259 // copy the leaves 00260 Ivy_GraphPrepare( p->pGraph, p->pCut, p->vFanins, p->pPerm ); 00261 00262 p->nScores[p->pMap[uTruthBest]]++; 00263 p->nNodesGained += GainBest; 00264 if ( fUseZeroCost || GainBest > 0 ) 00265 p->nNodesRewritten++; 00266 00267 /* 00268 if ( GainBest > 0 ) 00269 { 00270 Ivy_Cut_t * pCut = p->pCut; 00271 printf( "Node %5d. Using cut : {", Ivy_ObjId(pNode) ); 00272 for ( i = 0; i < pCut->nSize; i++ ) 00273 printf( " %5d(%2d)", Ivy_LeafId(pCut->pArray[i]), Ivy_LeafLat(pCut->pArray[i]) ); 00274 printf( " }\n" ); 00275 } 00276 */ 00277 00278 // report the progress 00279 if ( fVeryVerbose && GainBest > 0 ) 00280 { 00281 printf( "Node %6d : ", Ivy_ObjId(pNode) ); 00282 printf( "Fanins = %d. ", p->vFanins->nSize ); 00283 printf( "Save = %d. ", nNodesSaveCur ); 00284 printf( "Add = %d. ", nNodesSaveCur-GainBest ); 00285 printf( "GAIN = %d. ", GainBest ); 00286 printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); 00287 printf( "Class = %d. ", p->pMap[uTruthBest] ); 00288 printf( "\n" ); 00289 } 00290 return GainBest; 00291 }
Dec_Graph_t * Rwt_CutEvaluateSeq | ( | Ivy_Man_t * | pMan, | |
Rwt_Man_t * | p, | |||
Ivy_Obj_t * | pRoot, | |||
Ivy_Cut_t * | pCut, | |||
char * | pPerm, | |||
Vec_Ptr_t * | vFaninsCur, | |||
int | nNodesSaved, | |||
int * | pGainBest, | |||
unsigned | uTruth | |||
) | [static] |
Function*************************************************************
Synopsis [Evaluates the cut.]
Description []
SideEffects []
SeeAlso []
Definition at line 305 of file ivySeq.c.
00306 { 00307 Vec_Ptr_t * vSubgraphs; 00308 Dec_Graph_t * pGraphBest, * pGraphCur; 00309 Rwt_Node_t * pNode; 00310 int nNodesAdded, GainBest, i; 00311 // find the matching class of subgraphs 00312 vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); 00313 p->nSubgraphs += vSubgraphs->nSize; 00314 // determine the best subgraph 00315 GainBest = -1; 00316 Vec_PtrForEachEntry( vSubgraphs, pNode, i ) 00317 { 00318 // get the current graph 00319 pGraphCur = (Dec_Graph_t *)pNode->pNext; 00320 00321 // if ( pRoot->Id == 8648 ) 00322 // Dec_GraphPrint( stdout, pGraphCur, NULL, NULL ); 00323 // copy the leaves 00324 // Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) 00325 // Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; 00326 Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm ); 00327 00328 // detect how many unlabeled nodes will be reused 00329 nNodesAdded = Ivy_GraphToNetworkSeqCountSeq( pMan, pRoot, pGraphCur, nNodesSaved ); 00330 if ( nNodesAdded == -1 ) 00331 continue; 00332 assert( nNodesSaved >= nNodesAdded ); 00333 // count the gain at this node 00334 if ( GainBest < nNodesSaved - nNodesAdded ) 00335 { 00336 GainBest = nNodesSaved - nNodesAdded; 00337 pGraphBest = pGraphCur; 00338 } 00339 } 00340 if ( GainBest == -1 ) 00341 return NULL; 00342 *pGainBest = GainBest; 00343 return pGraphBest; 00344 }