summaryrefslogtreecommitdiffstats
path: root/src/base/abci/abcDelay.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/abci/abcDelay.c')
-rw-r--r--src/base/abci/abcDelay.c297
1 files changed, 297 insertions, 0 deletions
diff --git a/src/base/abci/abcDelay.c b/src/base/abci/abcDelay.c
index 91f175fa..847c7f1b 100644
--- a/src/base/abci/abcDelay.c
+++ b/src/base/abci/abcDelay.c
@@ -20,6 +20,7 @@
#include "abc.h"
#include "if.h"
+#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
@@ -652,6 +653,302 @@ Abc_Ntk_t * Abc_NtkSpeedup( Abc_Ntk_t * pNtk, int fUseLutLib, int Percentage, in
return pNtkNew;
}
+/**Function*************************************************************
+
+ Synopsis [Marks nodes for power-optimization.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Abc_NtkPowerEstimate( Abc_Ntk_t * pNtk, int fProbOne )
+{
+ extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
+ extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne );
+ Vec_Int_t * vProbs;
+ Vec_Int_t * vSwitching;
+ float * pProbability;
+ float * pSwitching;
+ Abc_Ntk_t * pNtkStr;
+ Aig_Man_t * pAig;
+ Aig_Obj_t * pObjAig;
+ Abc_Obj_t * pObjAbc, * pObjAbc2;
+ int i;
+ // start the resulting array
+ vProbs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
+ pProbability = (float *)vProbs->pArray;
+ // strash the network
+ pNtkStr = Abc_NtkStrash( pNtk, 0, 1, 0 );
+ Abc_NtkForEachObj( pNtk, pObjAbc, i )
+ if ( Abc_ObjRegular(pObjAbc->pTemp)->Type == ABC_FUNC_NONE )
+ pObjAbc->pTemp = NULL;
+ // map network into an AIG
+ pAig = Abc_NtkToDar( pNtkStr, 0, (int)(Abc_NtkLatchNum(pNtk) > 0) );
+ vSwitching = Saig_ManComputeSwitchProbs( pAig, 48, 16, fProbOne );
+ pSwitching = (float *)vSwitching->pArray;
+ Abc_NtkForEachObj( pNtk, pObjAbc, i )
+ {
+ if ( (pObjAbc2 = Abc_ObjRegular(pObjAbc->pTemp)) && (pObjAig = pObjAbc2->pTemp) )
+ pProbability[pObjAbc->Id] = pSwitching[pObjAig->Id];
+ }
+ Vec_IntFree( vSwitching );
+ Aig_ManStop( pAig );
+ Abc_NtkDelete( pNtkStr );
+ return vProbs;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Marks nodes for power-optimization.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkPowerPrint( Abc_Ntk_t * pNtk, Vec_Int_t * vProbs )
+{
+ Abc_Obj_t * pObj;
+ float * pProb, TotalProb = 0.0, ProbThis, Probs[5] = {0.0};
+ int i, nNodes = 0, nEdges = 0, Counter[5] = {0};
+ pProb = (float *)vProbs->pArray;
+ assert( Vec_IntSize(vProbs) >= Abc_NtkObjNumMax(pNtk) );
+ Abc_NtkForEachObj( pNtk, pObj, i )
+ {
+ if ( !Abc_ObjIsNode(pObj) && !Abc_ObjIsPi(pObj) )
+ continue;
+ nNodes++;
+ nEdges += Abc_ObjFanoutNum(pObj);
+ ProbThis = pProb[i] * Abc_ObjFanoutNum(pObj);
+ TotalProb += ProbThis;
+ assert( pProb[i] >= 0.0 && pProb[i] <= 0.5 );
+ if ( pProb[i] >= 0.4 )
+ {
+ Counter[4]++;
+ Probs[4] += ProbThis;
+ }
+ else if ( pProb[i] >= 0.3 )
+ {
+ Counter[3]++;
+ Probs[3] += ProbThis;
+ }
+ else if ( pProb[i] >= 0.2 )
+ {
+ Counter[2]++;
+ Probs[2] += ProbThis;
+ }
+ else if ( pProb[i] >= 0.1 )
+ {
+ Counter[1]++;
+ Probs[1] += ProbThis;
+ }
+ else
+ {
+ Counter[0]++;
+ Probs[0] += ProbThis;
+ }
+ }
+ printf( "Node distribution: " );
+ for ( i = 0; i < 5; i++ )
+ printf( "n%d%d = %6.2f%% ", i, i+1, 100.0 * Counter[i]/nNodes );
+ printf( "\n" );
+ printf( "Power distribution: " );
+ for ( i = 0; i < 5; i++ )
+ printf( "p%d%d = %6.2f%% ", i, i+1, 100.0 * Probs[i]/TotalProb );
+ printf( "\n" );
+ printf( "Total probs = %7.2f. ", TotalProb );
+ printf( "Total edges = %d. ", nEdges );
+ printf( "Average = %7.2f. ", TotalProb / nEdges );
+ printf( "\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Determines timing-critical edges of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Abc_NtkPowerCriticalEdges( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, float Limit, Vec_Int_t * vProbs )
+{
+ Abc_Obj_t * pFanin;
+ float * pProb = (float *)vProbs->pArray;
+ unsigned uResult = 0;
+ int k;
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ if ( pProb[pFanin->Id] >= Limit )
+ uResult |= (1 << k);
+ return uResult;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds choices to speed up the network by the given percentage.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Ntk_t * Abc_NtkPowerdown( Abc_Ntk_t * pNtk, int fUseLutLib, int Percentage, int Degree, int fVerbose, int fVeryVerbose )
+{
+ Abc_Ntk_t * pNtkNew;
+ Vec_Int_t * vProbs;
+ Vec_Ptr_t * vTimeCries, * vTimeFanins;
+ Abc_Obj_t * pNode, * pFanin, * pFanin2;
+ float * pProb, Limit;
+ int i, k, k2, Counter, CounterRes, nTimeCris;
+ unsigned * puPCEdges;
+ // compute the limit
+ Limit = 0.5 - (1.0 * Percentage / 100);
+ // perform computation of switching probability
+ vProbs = Abc_NtkPowerEstimate( pNtk, 0 );
+ pProb = (float *)vProbs->pArray;
+ // compute percentage of wires of each type
+ if ( fVerbose )
+ Abc_NtkPowerPrint( pNtk, vProbs );
+ // mark the power critical nodes and edges
+ puPCEdges = ALLOC( unsigned, Abc_NtkObjNumMax(pNtk) );
+ memset( puPCEdges, 0, sizeof(unsigned) * Abc_NtkObjNumMax(pNtk) );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ if ( pProb[pNode->Id] < Limit )
+ continue;
+ puPCEdges[pNode->Id] = Abc_NtkPowerCriticalEdges( pNtk, pNode, Limit, vProbs );
+ }
+/*
+ if ( fVerbose )
+ {
+ Counter = CounterRes = 0;
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+ Counter += Abc_ObjFaninNum(pNode);
+ CounterRes += Extra_WordCountOnes( puPCEdges[pNode->Id] );
+ }
+ printf( "Edges: Total = %7d. Critical = %7d. Ratio = %4.2f\n",
+ Counter, CounterRes, 1.0*CounterRes/Counter );
+ }
+*/
+ // start the resulting network
+ pNtkNew = Abc_NtkStrash( pNtk, 0, 1, 0 );
+
+ // collect nodes to be used for resynthesis
+ Counter = CounterRes = 0;
+ vTimeCries = Vec_PtrAlloc( 16 );
+ vTimeFanins = Vec_PtrAlloc( 16 );
+ Abc_NtkForEachNode( pNtk, pNode, i )
+ {
+// if ( pProb[pNode->Id] < Limit )
+// continue;
+ // count the number of non-PI power-critical nodes
+ nTimeCris = 0;
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ if ( !Abc_ObjIsCi(pFanin) && (puPCEdges[pNode->Id] & (1<<k)) )
+ nTimeCris++;
+ if ( !fVeryVerbose && nTimeCris == 0 )
+ continue;
+ Counter++;
+ // count the total number of power-critical second-generation nodes
+ Vec_PtrClear( vTimeCries );
+ if ( nTimeCris )
+ {
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ if ( !Abc_ObjIsCi(pFanin) && (puPCEdges[pNode->Id] & (1<<k)) )
+ Abc_ObjForEachFanin( pFanin, pFanin2, k2 )
+ if ( puPCEdges[pFanin->Id] & (1<<k2) )
+ Vec_PtrPushUnique( vTimeCries, pFanin2 );
+ }
+// if ( !fVeryVerbose && (Vec_PtrSize(vTimeCries) == 0 || Vec_PtrSize(vTimeCries) > Degree) )
+ if ( (Vec_PtrSize(vTimeCries) == 0 || Vec_PtrSize(vTimeCries) > Degree) )
+ continue;
+ CounterRes++;
+ // collect second generation nodes
+ Vec_PtrClear( vTimeFanins );
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ {
+ if ( Abc_ObjIsCi(pFanin) )
+ Vec_PtrPushUnique( vTimeFanins, pFanin );
+ else
+ Abc_ObjForEachFanin( pFanin, pFanin2, k2 )
+ Vec_PtrPushUnique( vTimeFanins, pFanin2 );
+ }
+ // print the results
+ if ( fVeryVerbose )
+ {
+ printf( "%5d Node %5d : %d %2d %2d ", Counter, pNode->Id,
+ nTimeCris, Vec_PtrSize(vTimeCries), Vec_PtrSize(vTimeFanins) );
+ Abc_ObjForEachFanin( pNode, pFanin, k )
+ printf( "%d(%.2f)%s ", pFanin->Id, pProb[pFanin->Id], (puPCEdges[pNode->Id] & (1<<k))? "*":"" );
+ printf( "\n" );
+ }
+ // add the node to choices
+ if ( Vec_PtrSize(vTimeCries) == 0 || Vec_PtrSize(vTimeCries) > Degree )
+ continue;
+ // order the fanins in the increasing order of criticalily
+ if ( Vec_PtrSize(vTimeCries) > 1 )
+ {
+ pFanin = Vec_PtrEntry( vTimeCries, 0 );
+ pFanin2 = Vec_PtrEntry( vTimeCries, 1 );
+// if ( Abc_ObjSlack(pFanin) < Abc_ObjSlack(pFanin2) )
+ if ( pProb[pFanin->Id] > pProb[pFanin2->Id] )
+ {
+ Vec_PtrWriteEntry( vTimeCries, 0, pFanin2 );
+ Vec_PtrWriteEntry( vTimeCries, 1, pFanin );
+ }
+ }
+ if ( Vec_PtrSize(vTimeCries) > 2 )
+ {
+ pFanin = Vec_PtrEntry( vTimeCries, 1 );
+ pFanin2 = Vec_PtrEntry( vTimeCries, 2 );
+// if ( Abc_ObjSlack(pFanin) < Abc_ObjSlack(pFanin2) )
+ if ( pProb[pFanin->Id] > pProb[pFanin2->Id] )
+ {
+ Vec_PtrWriteEntry( vTimeCries, 1, pFanin2 );
+ Vec_PtrWriteEntry( vTimeCries, 2, pFanin );
+ }
+ pFanin = Vec_PtrEntry( vTimeCries, 0 );
+ pFanin2 = Vec_PtrEntry( vTimeCries, 1 );
+// if ( Abc_ObjSlack(pFanin) < Abc_ObjSlack(pFanin2) )
+ if ( pProb[pFanin->Id] > pProb[pFanin2->Id] )
+ {
+ Vec_PtrWriteEntry( vTimeCries, 0, pFanin2 );
+ Vec_PtrWriteEntry( vTimeCries, 1, pFanin );
+ }
+ }
+ // add choice
+ Abc_NtkSpeedupNode( pNtk, pNtkNew, pNode, vTimeFanins, vTimeCries );
+ }
+ Vec_PtrFree( vTimeCries );
+ Vec_PtrFree( vTimeFanins );
+ free( puPCEdges );
+ if ( fVerbose )
+ printf( "Nodes: Total = %7d. Power-critical = %7d. Workable = %7d. Ratio = %4.2f\n",
+ Abc_NtkNodeNum(pNtk), Counter, CounterRes, 1.0*CounterRes/Counter );
+
+ // remove invalid choice nodes
+ Abc_AigForEachAnd( pNtkNew, pNode, i )
+ if ( pNode->pData )
+ {
+ if ( Abc_ObjFanoutNum(pNode->pData) > 0 )
+ pNode->pData = NULL;
+ }
+
+ // return the result
+ Vec_IntFree( vProbs );
+ return pNtkNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////