diff options
Diffstat (limited to 'src/base/abci/abcDelay.c')
| -rw-r--r-- | src/base/abci/abcDelay.c | 297 | 
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                                ///  //////////////////////////////////////////////////////////////////////// | 
