/**CFile**************************************************************** FileName [saigSwitch.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Sequential AIG package.] Synopsis [Returns switching propabilities.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: saigSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "saig.h" #include "base/main/main.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// typedef struct Saig_SimObj_t_ Saig_SimObj_t; struct Saig_SimObj_t_ { int iFan0; int iFan1; unsigned Type : 8; unsigned Number : 24; unsigned pData[1]; }; static inline int Saig_SimObjFaninC0( Saig_SimObj_t * pObj ) { return pObj->iFan0 & 1; } static inline int Saig_SimObjFaninC1( Saig_SimObj_t * pObj ) { return pObj->iFan1 & 1; } static inline int Saig_SimObjFanin0( Saig_SimObj_t * pObj ) { return pObj->iFan0 >> 1; } static inline int Saig_SimObjFanin1( Saig_SimObj_t * pObj ) { return pObj->iFan1 >> 1; } //typedef struct Aig_CMan_t_ Aig_CMan_t; //static Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Creates fast simulation manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Saig_SimObj_t * Saig_ManCreateMan( Aig_Man_t * p ) { Saig_SimObj_t * pAig, * pEntry; Aig_Obj_t * pObj; int i; pAig = ABC_CALLOC( Saig_SimObj_t, Aig_ManObjNumMax(p)+1 ); // printf( "Allocating %7.2f MB.\n", 1.0 * sizeof(Saig_SimObj_t) * (Aig_ManObjNumMax(p)+1)/(1<<20) ); Aig_ManForEachObj( p, pObj, i ) { pEntry = pAig + i; pEntry->Type = pObj->Type; if ( Aig_ObjIsCi(pObj) || i == 0 ) { if ( Saig_ObjIsLo(p, pObj) ) { pEntry->iFan0 = (Saig_ObjLoToLi(p, pObj)->Id << 1); pEntry->iFan1 = -1; } continue; } pEntry->iFan0 = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj); if ( Aig_ObjIsCo(pObj) ) continue; assert( Aig_ObjIsNode(pObj) ); pEntry->iFan1 = (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj); } pEntry = pAig + Aig_ManObjNumMax(p); pEntry->Type = AIG_OBJ_VOID; return pAig; } /**Function************************************************************* Synopsis [Simulated one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Saig_ManSimulateNode2( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj ) { Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj ); Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pObj ); if ( Saig_SimObjFaninC0(pObj) && Saig_SimObjFaninC1(pObj) ) pObj->pData[0] = ~(pObj0->pData[0] | pObj1->pData[0]); else if ( Saig_SimObjFaninC0(pObj) && !Saig_SimObjFaninC1(pObj) ) pObj->pData[0] = (~pObj0->pData[0] & pObj1->pData[0]); else if ( !Saig_SimObjFaninC0(pObj) && Saig_SimObjFaninC1(pObj) ) pObj->pData[0] = (pObj0->pData[0] & ~pObj1->pData[0]); else // if ( !Saig_SimObjFaninC0(pObj) && !Saig_SimObjFaninC1(pObj) ) pObj->pData[0] = (pObj0->pData[0] & pObj1->pData[0]); } /**Function************************************************************* Synopsis [Simulated one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Saig_ManSimulateNode( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj ) { Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj ); Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pObj ); pObj->pData[0] = (Saig_SimObjFaninC0(pObj)? ~pObj0->pData[0] : pObj0->pData[0]) & (Saig_SimObjFaninC1(pObj)? ~pObj1->pData[0] : pObj1->pData[0]); } /**Function************************************************************* Synopsis [Simulated buffer/inverter.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Saig_ManSimulateOneInput( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj ) { Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj ); if ( Saig_SimObjFaninC0(pObj) ) pObj->pData[0] = ~pObj0->pData[0]; else // if ( !Saig_SimObjFaninC0(pObj) ) pObj->pData[0] = pObj0->pData[0]; } /**Function************************************************************* Synopsis [Simulates the timeframes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Saig_ManSimulateFrames( Saig_SimObj_t * pAig, int nFrames, int nPref ) { Saig_SimObj_t * pEntry; int f; for ( f = 0; f < nFrames; f++ ) { for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ ) { if ( pEntry->Type == AIG_OBJ_AND ) Saig_ManSimulateNode( pAig, pEntry ); else if ( pEntry->Type == AIG_OBJ_CO ) Saig_ManSimulateOneInput( pAig, pEntry ); else if ( pEntry->Type == AIG_OBJ_CI ) { if ( pEntry->iFan0 == 0 ) // true PI pEntry->pData[0] = Aig_ManRandom( 0 ); else if ( f > 0 ) // register output Saig_ManSimulateOneInput( pAig, pEntry ); } else if ( pEntry->Type == AIG_OBJ_CONST1 ) pEntry->pData[0] = ~0; else if ( pEntry->Type != AIG_OBJ_NONE ) assert( 0 ); if ( f >= nPref ) pEntry->Number += Aig_WordCountOnes( pEntry->pData[0] ); } } } /**Function************************************************************* Synopsis [Computes switching activity of one node.] Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] SideEffects [] SeeAlso [] ***********************************************************************/ float Saig_ManComputeSwitching( int nOnes, int nSimWords ) { int nTotal = 32 * nSimWords; return (float)2.0 * nOnes / nTotal * (nTotal - nOnes) / nTotal; } /**Function************************************************************* Synopsis [Computes switching activity of one node.] Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] SideEffects [] SeeAlso [] ***********************************************************************/ float Saig_ManComputeProbOne( int nOnes, int nSimWords ) { int nTotal = 32 * nSimWords; return (float)nOnes / nTotal; } /**Function************************************************************* Synopsis [Computes switching activity of one node.] Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] SideEffects [] SeeAlso [] ***********************************************************************/ float Saig_ManComputeProbOnePlus( int nOnes, int nSimWords, int fCompl ) { int nTotal = 32 * nSimWords; if ( fCompl ) return (float)(nTotal-nOnes) / nTotal; else return (float)nOnes / nTotal; } /**Function************************************************************* Synopsis [Compute switching probabilities of all nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Saig_ManComputeSwitchProb4s( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ) { Saig_SimObj_t * pAig, * pEntry; Vec_Int_t * vSwitching; float * pSwitching; int nFramesReal; abctime clk;//, clkTotal = Abc_Clock(); vSwitching = Vec_IntStart( Aig_ManObjNumMax(p) ); pSwitching = (float *)vSwitching->pArray; clk = Abc_Clock(); pAig = Saig_ManCreateMan( p ); //ABC_PRT( "\nCreation ", Abc_Clock() - clk ); Aig_ManRandom( 1 ); // get the number of frames to simulate // if the parameter "seqsimframes" is defined, use it // otherwise, use the given number of frames "nFrames" nFramesReal = nFrames; if ( Abc_FrameReadFlag("seqsimframes") ) nFramesReal = atoi( Abc_FrameReadFlag("seqsimframes") ); if ( nFramesReal <= nPref ) { printf( "The total number of frames (%d) should exceed prefix (%d).\n", nFramesReal, nPref );\ printf( "Setting the total number of frames to be %d.\n", nFrames ); nFramesReal = nFrames; } //printf( "Simulating %d frames.\n", nFramesReal ); clk = Abc_Clock(); Saig_ManSimulateFrames( pAig, nFramesReal, nPref ); //ABC_PRT( "Simulation", Abc_Clock() - clk ); clk = Abc_Clock(); for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ ) { /* if ( pEntry->Type == AIG_OBJ_AND ) { Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pEntry ); Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pEntry ); printf( "%5.2f = %5.2f * %5.2f (%7.4f)\n", Saig_ManComputeProbOnePlus( pEntry->Number, nFrames - nPref, 0 ), Saig_ManComputeProbOnePlus( pObj0->Number, nFrames - nPref, Saig_SimObjFaninC0(pEntry) ), Saig_ManComputeProbOnePlus( pObj1->Number, nFrames - nPref, Saig_SimObjFaninC1(pEntry) ), Saig_ManComputeProbOnePlus( pEntry->Number, nFrames - nPref, 0 ) - Saig_ManComputeProbOnePlus( pObj0->Number, nFrames - nPref, Saig_SimObjFaninC0(pEntry) ) * Saig_ManComputeProbOnePlus( pObj1->Number, nFrames - nPref, Saig_SimObjFaninC1(pEntry) ) ); } */ if ( fProbOne ) pSwitching[pEntry-pAig] = Saig_ManComputeProbOne( pEntry->Number, nFramesReal - nPref ); else pSwitching[pEntry-pAig] = Saig_ManComputeSwitching( pEntry->Number, nFramesReal - nPref ); //printf( "%3d : %7.2f\n", pEntry-pAig, pSwitching[pEntry-pAig] ); } ABC_FREE( pAig ); //ABC_PRT( "Switch ", Abc_Clock() - clk ); //ABC_PRT( "TOTAL ", Abc_Clock() - clkTotal ); // Aig_CManCreate( p ); return vSwitching; } typedef struct Aig_CMan_t_ Aig_CMan_t; struct Aig_CMan_t_ { // parameters int nIns; int nNodes; int nOuts; // current state int iNode; int iDiff0; int iDiff1; unsigned char * pCur; // stored data int iPrev; int nBytes; unsigned char Data[0]; }; /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_CMan_t * Aig_CManStart( int nIns, int nNodes, int nOuts ) { Aig_CMan_t * p; p = (Aig_CMan_t *)ABC_ALLOC( char, sizeof(Aig_CMan_t) + 2*(2*nNodes + nOuts) ); memset( p, 0, sizeof(Aig_CMan_t) ); // set parameters p->nIns = nIns; p->nOuts = nOuts; p->nNodes = nNodes; p->nBytes = 2*(2*nNodes + nOuts); // prepare the manager p->iNode = 1 + p->nIns; p->iPrev = -1; p->pCur = p->Data; return p; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_CManStop( Aig_CMan_t * p ) { ABC_FREE( p ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_CManRestart( Aig_CMan_t * p ) { assert( p->iNode == 1 + p->nIns + p->nNodes + p->nOuts ); p->iNode = 1 + p->nIns; p->iPrev = -1; p->pCur = p->Data; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_CManStoreNum( Aig_CMan_t * p, unsigned x ) { while ( x & ~0x7f ) { *p->pCur++ = (x & 0x7f) | 0x80; x >>= 7; } *p->pCur++ = x; assert( p->pCur - p->Data < p->nBytes - 10 ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_CManRestoreNum( Aig_CMan_t * p ) { int ch, i, x = 0; for ( i = 0; (ch = *p->pCur++) & 0x80; i++ ) x |= (ch & 0x7f) << (7 * i); return x | (ch << (7 * i)); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_CManAddNode( Aig_CMan_t * p, int iFan0, int iFan1 ) { assert( iFan0 < iFan1 ); assert( iFan1 < (p->iNode << 1) ); Aig_CManStoreNum( p, (p->iNode++ << 1) - iFan1 ); Aig_CManStoreNum( p, iFan1 - iFan0 ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_CManAddPo( Aig_CMan_t * p, int iFan0 ) { if ( p->iPrev == -1 ) Aig_CManStoreNum( p, p->iNode - iFan0 ); else if ( p->iPrev <= iFan0 ) Aig_CManStoreNum( p, (iFan0 - p->iPrev) << 1 ); else Aig_CManStoreNum( p,((p->iPrev - iFan0) << 1) | 1 ); p->iPrev = iFan0; p->iNode++; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_CManGetNode( Aig_CMan_t * p, int * piFan0, int * piFan1 ) { *piFan1 = (p->iNode++ << 1) - Aig_CManRestoreNum( p ); *piFan0 = *piFan1 - Aig_CManRestoreNum( p ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_CManGetPo( Aig_CMan_t * p ) { int Num = Aig_CManRestoreNum( p ); if ( p->iPrev == -1 ) p->iPrev = p->iNode; p->iNode++; if ( Num & 1 ) return p->iPrev = p->iPrev + (Num >> 1); return p->iPrev = p->iPrev - (Num >> 1); } /**Function************************************************************* Synopsis [Compute switching probabilities of all nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p ) { Aig_CMan_t * pCMan; Aig_Obj_t * pObj; int i; pCMan = Aig_CManStart( Aig_ManCiNum(p), Aig_ManNodeNum(p), Aig_ManCoNum(p) ); Aig_ManForEachNode( p, pObj, i ) Aig_CManAddNode( pCMan, (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj), (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj) ); Aig_ManForEachCo( p, pObj, i ) Aig_CManAddPo( pCMan, (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj) ); printf( "\nBytes alloc = %5d. Bytes used = %7d. Ave per node = %4.2f. \n", pCMan->nBytes, (int)(pCMan->pCur - pCMan->Data), 1.0 * (pCMan->pCur - pCMan->Data) / (pCMan->nNodes + pCMan->nOuts ) ); // Aig_CManStop( pCMan ); return pCMan; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END