diff options
-rw-r--r-- | src/aig/gia/giaCof.c | 106 | ||||
-rw-r--r-- | src/aig/gia/giaMuxes.c | 9 | ||||
-rw-r--r-- | src/base/abci/abc.c | 22 |
3 files changed, 114 insertions, 23 deletions
diff --git a/src/aig/gia/giaCof.c b/src/aig/gia/giaCof.c index 43cce6ac..c6ccb7d1 100644 --- a/src/aig/gia/giaCof.c +++ b/src/aig/gia/giaCof.c @@ -549,6 +549,48 @@ void Cof_ManPrintHighFanout( Cof_Man_t * p, int nNodes ) Vec_PtrFree( vNodes ); } + +/**Function************************************************************* + + Synopsis [Compute MFFC size of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cof_NodeDeref_rec( Cof_Obj_t * pNode ) +{ + if ( pNode->nFanins == 0 ) + return 0; + if ( --pNode->nFanouts > 0 ) + return 0; + return 1 + Cof_NodeDeref_rec( Cof_ObjFanin(pNode, 0) ) + + Cof_NodeDeref_rec( Cof_ObjFanin(pNode, 1) ); +} +int Cof_NodeRef_rec( Cof_Obj_t * pNode ) +{ + if ( pNode->nFanins == 0 ) + return 0; + if ( pNode->nFanouts++ > 0 ) + return 0; + return 1 + Cof_NodeRef_rec( Cof_ObjFanin(pNode, 0) ) + + Cof_NodeRef_rec( Cof_ObjFanin(pNode, 1) ); +} +static inline int Cof_ObjMffcSize( Cof_Obj_t * pNode ) +{ + int Count1, Count2, nFanout; + nFanout = pNode->nFanouts; + pNode->nFanouts = 1; + Count1 = Cof_NodeDeref_rec( pNode ); + Count2 = Cof_NodeRef_rec( pNode ); + pNode->nFanouts = nFanout; + assert( Count1 == Count2 ); + return Count1; +} + /**Function************************************************************* Synopsis [Prints the distribution of fanins/fanouts in the network.] @@ -564,28 +606,33 @@ void Cof_ManPrintFanio( Cof_Man_t * p ) { char Buffer[100]; Cof_Obj_t * pNode; - Vec_Int_t * vFanins, * vFanouts; - int nFanins, nFanouts, nFaninsMax, nFanoutsMax, nFaninsAll, nFanoutsAll; - int i, k, nSizeMax; + Vec_Int_t * vFanins, * vFanouts, * vMffcs; + int nFanins, nFanouts, nMffcs, nFaninsMax, nFanoutsMax, nMffcsMax, nFaninsAll, nFanoutsAll, nMffcsAll; + int i, k, nSizeMax, nMffcNodes = 0; // determine the largest fanin and fanout - nFaninsMax = nFanoutsMax = 0; - nFaninsAll = nFanoutsAll = 0; + nFaninsMax = nFanoutsMax = nMffcsMax = 0; + nFaninsAll = nFanoutsAll = nMffcsAll = 0; Cof_ManForEachNode( p, pNode, i ) { if ( i == 0 ) continue; nFanins = Cof_ObjFaninNum(pNode); nFanouts = Cof_ObjFanoutNum(pNode); + nMffcs = pNode->nFanouts > 1 ? Cof_ObjMffcSize(pNode) : 0; nFaninsAll += nFanins; nFanoutsAll += nFanouts; - nFaninsMax = Abc_MaxInt( nFaninsMax, nFanins ); + nMffcsAll += nMffcs; + nFaninsMax = Abc_MaxInt( nFaninsMax, nFanins ); nFanoutsMax = Abc_MaxInt( nFanoutsMax, nFanouts ); + nMffcsMax = Abc_MaxInt( nMffcsMax, nMffcs ); } // allocate storage for fanin/fanout numbers nSizeMax = Abc_MaxInt( 10 * (Abc_Base10Log(nFaninsMax) + 1), 10 * (Abc_Base10Log(nFanoutsMax) + 1) ); + nSizeMax = Abc_MaxInt( 10 * (Abc_Base10Log(nMffcsMax) + 1), nSizeMax ); vFanins = Vec_IntStart( nSizeMax ); vFanouts = Vec_IntStart( nSizeMax ); + vMffcs = Vec_IntStart( nSizeMax ); // count the number of fanins and fanouts Cof_ManForEachNode( p, pNode, i ) @@ -593,7 +640,7 @@ void Cof_ManPrintFanio( Cof_Man_t * p ) if ( i == 0 ) continue; nFanins = Cof_ObjFaninNum(pNode); nFanouts = Cof_ObjFanoutNum(pNode); -// nFanouts = Cof_NodeMffcSize(pNode); + nMffcs = pNode->nFanouts > 1 ? Cof_ObjMffcSize(pNode) : 0; if ( nFanins < 10 ) Vec_IntAddToEntry( vFanins, nFanins, 1 ); @@ -624,13 +671,33 @@ void Cof_ManPrintFanio( Cof_Man_t * p ) Vec_IntAddToEntry( vFanouts, 50 + nFanouts/100000, 1 ); else if ( nFanouts < 10000000 ) Vec_IntAddToEntry( vFanouts, 60 + nFanouts/1000000, 1 ); + + if ( nMffcs == 0 ) + continue; + nMffcNodes++; + + if ( nMffcs < 10 ) + Vec_IntAddToEntry( vMffcs, nMffcs, 1 ); + else if ( nMffcs < 100 ) + Vec_IntAddToEntry( vMffcs, 10 + nMffcs/10, 1 ); + else if ( nMffcs < 1000 ) + Vec_IntAddToEntry( vMffcs, 20 + nMffcs/100, 1 ); + else if ( nMffcs < 10000 ) + Vec_IntAddToEntry( vMffcs, 30 + nMffcs/1000, 1 ); + else if ( nMffcs < 100000 ) + Vec_IntAddToEntry( vMffcs, 40 + nMffcs/10000, 1 ); + else if ( nMffcs < 1000000 ) + Vec_IntAddToEntry( vMffcs, 50 + nMffcs/100000, 1 ); + else if ( nMffcs < 10000000 ) + Vec_IntAddToEntry( vMffcs, 60 + nMffcs/1000000, 1 ); } - printf( "The distribution of fanins and fanouts in the network:\n" ); - printf( " Number Nodes with fanin Nodes with fanout\n" ); + printf( "The distribution of fanins, fanouts. and MFFCs in the network:\n" ); + printf( " Number Nodes with fanin Nodes with fanout Nodes with MFFC\n" ); + for ( k = 0; k < nSizeMax; k++ ) { - if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 ) + if ( vFanins->pArray[k] == 0 && vFanouts->pArray[k] == 0 && vMffcs->pArray[k] == 0 ) continue; if ( k < 10 ) printf( "%15d : ", k ); @@ -642,20 +709,27 @@ void Cof_ManPrintFanio( Cof_Man_t * p ) if ( vFanins->pArray[k] == 0 ) printf( " " ); else - printf( "%12d ", vFanins->pArray[k] ); + printf( "%11d ", vFanins->pArray[k] ); printf( " " ); if ( vFanouts->pArray[k] == 0 ) printf( " " ); else printf( "%12d ", vFanouts->pArray[k] ); + printf( " " ); + if ( vMffcs->pArray[k] == 0 ) + printf( " " ); + else + printf( " %12d ", vMffcs->pArray[k] ); printf( "\n" ); } Vec_IntFree( vFanins ); Vec_IntFree( vFanouts ); + Vec_IntFree( vMffcs ); - printf( "Fanins: Max = %d. Ave = %.2f. Fanouts: Max = %d. Ave = %.2f.\n", - nFaninsMax, 1.0*nFaninsAll/Cof_ManNodeNum(p), - nFanoutsMax, 1.0*nFanoutsAll/Cof_ManNodeNum(p) ); + printf( "Fanins: Max = %d. Ave = %.2f. Fanouts: Max = %d. Ave = %.2f. MFFCs: Max = %d. Ave = %.2f.\n", + nFaninsMax, 1.0*nFaninsAll /Cof_ManNodeNum(p), + nFanoutsMax, 1.0*nFanoutsAll/Cof_ManNodeNum(p), + nMffcsMax, 1.0*nMffcsAll /nMffcNodes ); } /**Function************************************************************* @@ -678,12 +752,16 @@ void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes ) p->pLevels = ABC_CALLOC( int, p->nLevels ); Cof_ManPrintFanio( p ); + if ( nNodes > 0 ) + { Cof_ManResetTravId( p ); Gia_ManHashStart( pGia ); Cof_ManPrintHighFanout( p, nNodes ); Gia_ManHashStop( pGia ); ABC_PRMn( "Memory for logic network", 4*p->nObjData ); ABC_PRT( "Time", Abc_Clock() - clk ); + } + Cof_ManStop( p ); } diff --git a/src/aig/gia/giaMuxes.c b/src/aig/gia/giaMuxes.c index 96dda567..c0c3b18f 100644 --- a/src/aig/gia/giaMuxes.c +++ b/src/aig/gia/giaMuxes.c @@ -371,7 +371,7 @@ void Gia_MuxStructDump_rec( Gia_Man_t * p, int iObj, int fFirst, Vec_Str_t * vSt Vec_StrPush( vStr, ']' ); } } -void Gia_MuxStructDump( Gia_Man_t * p, int iObj, Vec_Str_t * vStr, int nDigitsNum, int nDigitsId ) +int Gia_MuxStructDump( Gia_Man_t * p, int iObj, Vec_Str_t * vStr, int nDigitsNum, int nDigitsId ) { int Count1, Count2; assert( Gia_ObjIsMuxId(p, iObj) ); @@ -382,6 +382,7 @@ void Gia_MuxStructDump( Gia_Man_t * p, int iObj, Vec_Str_t * vStr, int nDigitsNu Vec_StrPush( vStr, '\0' ); Count2 = Gia_MuxRef( p, iObj ); assert( Count1 == Count2 ); + return Count1; } /**Function************************************************************* @@ -530,7 +531,9 @@ void Gia_ManMuxProfiling( Gia_Man_t * p ) if ( Gia_ObjRefNumId(pNew, i) == 1 && Gia_ObjIsMuxId(pNew, Vec_IntEntry(vFans, i)) ) continue; // this node is the root of the MUX structure - create hash key - Gia_MuxStructDump( pNew, i, vStr, 3, nDigitsId ); + Counter = Gia_MuxStructDump( pNew, i, vStr, 3, nDigitsId ); + if ( Counter == 1 ) + continue; iStructId = Abc_NamStrFindOrAdd( pMan->pNames, Vec_StrArray(vStr), &fFound ); if ( !fFound ) Vec_WecPushLevel( pMan->vTops ); @@ -542,7 +545,7 @@ void Gia_ManMuxProfiling( Gia_Man_t * p ) printf( "MUX structure profile for AIG \"%s\":\n", p->pName ); printf( "Total MUXes = %d. Total trees = %d. Unique trees = %d. Memory = %.2f MB ", - Gia_ManMuxNum(pNew), Vec_WecSizeSize(pMan->vTops), Vec_WecSize(pMan->vTops), + Gia_ManMuxNum(pNew), Vec_WecSizeSize(pMan->vTops), Vec_WecSize(pMan->vTops)-1, 1.0*Abc_NamMemUsed(pMan->pNames)/(1<<20) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 6c869c7d..0b183da9 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -25512,7 +25512,7 @@ usage: int Abc_CommandAbc9PFan( Abc_Frame_t * pAbc, int argc, char ** argv ) { int c; - int nNodes = 40; + int nNodes = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF ) { @@ -27838,16 +27838,18 @@ usage: int Abc_CommandAbc9BalanceLut( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Gia_Man_t * Gia_ManBalanceLut( Gia_Man_t * p, int nLutSize, int nCutNum, int fVerbose ); - extern Gia_Man_t * Str_NormalizeTest( Gia_Man_t * p, int nLutSize, int fUseMuxes, int fVerbose ); + extern Gia_Man_t * Str_NormalizeTest( Gia_Man_t * p, int nLutSize, int fUseMuxes, int fRecursive, int fOptArea, int fVerbose ); Gia_Man_t * pTemp = NULL; int fUseOld = 0; int nLutSize = 6; int nCutNum = 8; int fUseMuxes = 1; + int fRecursive = 1; + int fOptArea = 0; int c, fVerbose = 0; int fVeryVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCamvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCnmravwh" ) ) != EOF ) { switch ( c ) { @@ -27873,12 +27875,18 @@ int Abc_CommandAbc9BalanceLut( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nCutNum < 0 ) goto usage; break; - case 'a': + case 'n': fUseOld ^= 1; break; case 'm': fUseMuxes ^= 1; break; + case 'r': + fRecursive ^= 1; + break; + case 'a': + fOptArea ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -27899,16 +27907,18 @@ int Abc_CommandAbc9BalanceLut( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fUseOld ) pTemp = Gia_ManBalanceLut( pAbc->pGia, nLutSize, nCutNum, fVerbose ); else - pTemp = Str_NormalizeTest( pAbc->pGia, nLutSize, fUseMuxes, fVerbose ); + pTemp = Str_NormalizeTest( pAbc->pGia, nLutSize, fUseMuxes, fRecursive, fOptArea, fVerbose ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &blut [-KC num] [-mvh]\n" ); + Abc_Print( -2, "usage: &blut [-KC num] [-mravh]\n" ); Abc_Print( -2, "\t performs AIG balancing for the given LUT size\n" ); Abc_Print( -2, "\t-K num : LUT size for the mapping (2 <= K <= %d) [default = %d]\n", 6, nLutSize ); Abc_Print( -2, "\t-C num : the max number of priority cuts (1 <= C <= %d) [default = %d]\n", 8, nCutNum ); Abc_Print( -2, "\t-m : toggle performing MUX restructuring [default = %s]\n", fUseMuxes? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle performing recursive restructuring [default = %s]\n", fRecursive? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle performing area-oriented restructuring [default = %s]\n", fOptArea? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); // Abc_Print( -2, "\t-w : toggle printing additional information [default = %s]\n", fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); |