| /**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 |
| |