/**CFile**************************************************************** FileName [saigSimFast.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Sequential AIG package.] Synopsis [Fast sequential AIG simulator.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: saigSimFast.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 /// //////////////////////////////////////////////////////////////////////// // the AIG manager typedef struct Faig_Man_t_ Faig_Man_t; struct Faig_Man_t_ { // parameters int nPis; int nPos; int nCis; int nCos; int nFfs; int nNos; // offsets int nPis1; int nCis1; int nCisNos1; int nCisNosPos1; int nObjs; // allocated data int nWords; int pObjs[0]; }; static inline int Faig_CheckIdPi( Faig_Man_t * p, int i ) { return i >= 1 && i < p->nPis1; } static inline int Faig_CheckIdLo( Faig_Man_t * p, int i ) { return i >= p->nPis1 && i < p->nCis1; } static inline int Faig_CheckIdNo( Faig_Man_t * p, int i ) { return i >= p->nCis1 && i < p->nCisNos1; } static inline int Faig_CheckIdPo( Faig_Man_t * p, int i ) { return i >= p->nCisNos1 && i < p->nCisNosPos1; } static inline int Faig_CheckIdLi( Faig_Man_t * p, int i ) { return i >= p->nCisNosPos1 && i < p->nObjs; } static inline int Faig_CheckIdCo( Faig_Man_t * p, int i ) { return i >= p->nCisNos1 && i < p->nObjs; } static inline int Faig_CheckIdObj( Faig_Man_t * p, int i ) { return i >= 0 && i < p->nObjs; } static inline int Faig_ObjIdToNumPi( Faig_Man_t * p, int i ) { assert( Faig_CheckIdPi(p,i) ); return i - 1; } static inline int Faig_ObjIdToNumLo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLo(p,i) ); return i - p->nPis1; } static inline int Faig_ObjIdToNumNo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdNo(p,i) ); return i - p->nCis1; } static inline int Faig_ObjIdToNumPo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdPo(p,i) ); return i - p->nCisNos1; } static inline int Faig_ObjIdToNumLi( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLi(p,i) ); return i - p->nCisNosPos1; } static inline int Faig_ObjIdToNumCo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdCo(p,i) ); return i - p->nCisNos1; } static inline int Faig_ObjLoToLi( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLo(p,i) ); return p->nObjs - (p->nCis1 - i); } static inline int Faig_ObjLiToLo( Faig_Man_t * p, int i ) { assert( Faig_CheckIdLi(p,i) ); return p->nCis1 - (p->nObjs - i); } static inline int Faig_NodeChild0( Faig_Man_t * p, int n ) { return p->pObjs[n<<1]; } static inline int Faig_NodeChild1( Faig_Man_t * p, int n ) { return p->pObjs[(n<<1)+1]; } static inline int Faig_CoChild0( Faig_Man_t * p, int n ) { return p->pObjs[(p->nNos<<1)+n]; } static inline int Faig_ObjFaninC( int iFan ) { return iFan & 1; } static inline int Faig_ObjFanin( int iFan ) { return iFan >> 1; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Checks if the manager is correct.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Faig_ManIsCorrect( Aig_Man_t * pAig ) { return Aig_ManObjNumMax(pAig) == 1 + Aig_ManCiNum(pAig) + Aig_ManNodeNum(pAig) + Aig_ManCoNum(pAig); } /**Function************************************************************* Synopsis [Creates fast simulation manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Faig_Man_t * Faig_ManAlloc( Aig_Man_t * pAig ) { Faig_Man_t * p; int nWords; // assert( Faig_ManIsCorrect(pAig) ); nWords = 2 * Aig_ManNodeNum(pAig) + Aig_ManCoNum(pAig); p = (Faig_Man_t *)ABC_ALLOC( char, sizeof(Faig_Man_t) + sizeof(int) * nWords ); //printf( "Allocating %7.2f MB.\n", 1.0 * (sizeof(Faig_Man_t) + sizeof(int) * nWords)/(1<<20) ); memset( p, 0, sizeof(Faig_Man_t) ); p->nPis = Aig_ManCiNum(pAig) - Aig_ManRegNum(pAig); p->nPos = Aig_ManCoNum(pAig) - Aig_ManRegNum(pAig); p->nCis = Aig_ManCiNum(pAig); p->nCos = Aig_ManCoNum(pAig); p->nFfs = Aig_ManRegNum(pAig); p->nNos = Aig_ManNodeNum(pAig); // offsets p->nPis1 = p->nPis + 1; p->nCis1 = p->nCis + 1; p->nCisNos1 = p->nCis + p->nNos + 1; p->nCisNosPos1 = p->nCis + p->nNos + p->nPos + 1; p->nObjs = p->nCis + p->nNos + p->nCos + 1; p->nWords = nWords; return p; } /**Function************************************************************* Synopsis [Creates fast simulation manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Faig_Man_t * Faig_ManCreate( Aig_Man_t * pAig ) { Faig_Man_t * p; Aig_Obj_t * pObj; int i, iWord = 0; p = Faig_ManAlloc( pAig ); Aig_ManForEachNode( pAig, pObj, i ) { p->pObjs[iWord++] = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj); p->pObjs[iWord++] = (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj); } Aig_ManForEachCo( pAig, pObj, i ) p->pObjs[iWord++] = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj); assert( iWord == p->nWords ); return p; } /**Function************************************************************* Synopsis [Simulates one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline unsigned Faig_SimulateNode( Faig_Man_t * p, int Id, unsigned * pSimInfo ) { int n = Faig_ObjIdToNumNo( p, Id ); int iFan0 = Faig_NodeChild0( p, n ); int iFan1 = Faig_NodeChild1( p, n ); if ( Faig_ObjFaninC(iFan0) && Faig_ObjFaninC(iFan1) ) return ~(pSimInfo[Faig_ObjFanin(iFan0)] | pSimInfo[Faig_ObjFanin(iFan1)]); if ( Faig_ObjFaninC(iFan0) && !Faig_ObjFaninC(iFan1) ) return (~pSimInfo[Faig_ObjFanin(iFan0)] & pSimInfo[Faig_ObjFanin(iFan1)]); if ( !Faig_ObjFaninC(iFan0) && Faig_ObjFaninC(iFan1) ) return (pSimInfo[Faig_ObjFanin(iFan0)] & ~pSimInfo[Faig_ObjFanin(iFan1)]); // if ( !Faig_ObjFaninC(iFan0) && !Faig_ObjFaninC(iFan1) ) return (pSimInfo[Faig_ObjFanin(iFan0)] & pSimInfo[Faig_ObjFanin(iFan1)]); } /**Function************************************************************* Synopsis [Simulates one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline unsigned Faig_SimulateCo( Faig_Man_t * p, int Id, unsigned * pSimInfo ) { int n = Faig_ObjIdToNumCo( p, Id ); int iFan0 = Faig_CoChild0( p, n ); if ( Faig_ObjFaninC(iFan0) ) return ~pSimInfo[Faig_ObjFanin(iFan0)]; // if ( !Faig_ObjFaninC(iFan0) ) return pSimInfo[Faig_ObjFanin(iFan0)]; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline unsigned Faig_SimulateRandomShift( unsigned uOld ) { return (uOld << 16) | ((uOld ^ Aig_ManRandom(0)) & 0xffff); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline unsigned Faig_SimulateTransferShift( unsigned uOld, unsigned uNew ) { return (uOld << 16) | (uNew & 0xffff); } /**Function************************************************************* Synopsis [Simulates the timeframes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int * Faig_ManSimulateFrames( Faig_Man_t * p, int nFrames, int nPref, int fTrans ) { int * pNumOnes = ABC_CALLOC( int, p->nObjs ); unsigned * pSimInfo = ABC_ALLOC( unsigned, p->nObjs ); int f, i; //printf( "Allocating %7.2f MB.\n", 1.0 * 4 * p->nObjs/(1<<20) ); //printf( "Allocating %7.2f MB.\n", 1.0 * 4 * p->nObjs/(1<<20) ); // set constant 1 pSimInfo[0] = ~0; for ( f = 0; f < nFrames; f++ ) { if ( fTrans ) { for ( i = 1; i < p->nPis1; i++ ) pSimInfo[i] = f? Faig_SimulateRandomShift( pSimInfo[i] ) : Aig_ManRandom( 0 ); for ( ; i < p->nCis1; i++ ) pSimInfo[i] = f? Faig_SimulateTransferShift( pSimInfo[i], pSimInfo[Faig_ObjLoToLi(p,i)] ) : 0; } else { for ( i = 1; i < p->nPis1; i++ ) pSimInfo[i] = Aig_ManRandom( 0 ); for ( ; i < p->nCis1; i++ ) pSimInfo[i] = f? pSimInfo[Faig_ObjLoToLi(p,i)] : 0; } for ( ; i < p->nCisNos1; i++ ) pSimInfo[i] = Faig_SimulateNode( p, i, pSimInfo ); for ( ; i < p->nObjs; i++ ) pSimInfo[i] = Faig_SimulateCo( p, i, pSimInfo ); if ( f < nPref ) continue; if ( fTrans ) { for ( i = 0; i < p->nObjs; i++ ) pNumOnes[i] += Aig_WordCountOnes( (pSimInfo[i] ^ (pSimInfo[i] >> 16)) & 0xffff ); } else { for ( i = 0; i < p->nObjs; i++ ) pNumOnes[i] += Aig_WordCountOnes( pSimInfo[i] ); } } ABC_FREE( pSimInfo ); return pNumOnes; } /**Function************************************************************* Synopsis [Computes switching activity of one node.] Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ] SideEffects [] SeeAlso [] ***********************************************************************/ float Faig_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 Faig_ManComputeProbOne( int nOnes, int nSimWords ) { int nTotal = 32 * nSimWords; return (float)nOnes / nTotal; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Faig_ManComputeSwitchProbs4( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ) { int fTrans = 1; Faig_Man_t * pAig; Vec_Int_t * vSwitching; int * pProbs; float * pSwitching; int nFramesReal; abctime clk;//, clkTotal = Abc_Clock(); if ( fProbOne ) fTrans = 0; vSwitching = Vec_IntStart( Aig_ManObjNumMax(p) ); pSwitching = (float *)vSwitching->pArray; clk = Abc_Clock(); pAig = Faig_ManCreate( 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(); pProbs = Faig_ManSimulateFrames( pAig, nFramesReal, nPref, fTrans ); //ABC_PRT( "Simulation", Abc_Clock() - clk ); clk = Abc_Clock(); if ( fTrans ) { Aig_Obj_t * pObj; int i, Counter = 0; pObj = Aig_ManConst1(p); pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 ); Aig_ManForEachCi( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 ); Aig_ManForEachNode( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 ); Aig_ManForEachCo( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], (nFramesReal - nPref)/2 ); assert( Counter == pAig->nObjs ); } else if ( fProbOne ) { Aig_Obj_t * pObj; int i, Counter = 0; pObj = Aig_ManConst1(p); pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref ); Aig_ManForEachCi( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref ); Aig_ManForEachNode( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref ); Aig_ManForEachCo( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeProbOne( pProbs[Counter++], nFramesReal - nPref ); assert( Counter == pAig->nObjs ); } else { Aig_Obj_t * pObj; int i, Counter = 0; pObj = Aig_ManConst1(p); pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref ); Aig_ManForEachCi( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref ); Aig_ManForEachNode( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref ); Aig_ManForEachCo( p, pObj, i ) pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref ); assert( Counter == pAig->nObjs ); } ABC_FREE( pProbs ); ABC_FREE( pAig ); //ABC_PRT( "Switch ", Abc_Clock() - clk ); //ABC_PRT( "TOTAL ", Abc_Clock() - clkTotal ); return vSwitching; } /**Function************************************************************* Synopsis [Computes probability of switching (or of being 1).] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Saig_ManComputeSwitchProb3s( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ) { // return Faig_ManComputeSwitchProbs( p, nFrames, nPref, fProbOne ); return NULL; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END