summaryrefslogtreecommitdiffstats
path: root/src/aig/saig/saigSimFast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/aig/saig/saigSimFast.c')
-rw-r--r--src/aig/saig/saigSimFast.c443
1 files changed, 443 insertions, 0 deletions
diff --git a/src/aig/saig/saigSimFast.c b/src/aig/saig/saigSimFast.c
new file mode 100644
index 00000000..09bb6a06
--- /dev/null
+++ b/src/aig/saig/saigSimFast.c
@@ -0,0 +1,443 @@
+/**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"
+
+////////////////////////////////////////////////////////////////////////
+/// 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_ManPiNum(pAig) + Aig_ManNodeNum(pAig) + Aig_ManPoNum(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_ManPoNum(pAig);
+ p = (Faig_Man_t *)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_ManPiNum(pAig) - Aig_ManRegNum(pAig);
+ p->nPos = Aig_ManPoNum(pAig) - Aig_ManRegNum(pAig);
+ p->nCis = Aig_ManPiNum(pAig);
+ p->nCos = Aig_ManPoNum(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_ManForEachPo( 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 = CALLOC( unsigned, p->nObjs );
+ unsigned * pSimInfo = 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] );
+ }
+ }
+ 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_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
+{
+ extern char * Abc_FrameReadFlag( char * pFlag );
+ int fTrans = 1;
+ Faig_Man_t * pAig;
+ Vec_Int_t * vSwitching;
+ int * pProbs;
+ float * pSwitching;
+ int nFramesReal, clk, clkTotal = clock();
+ if ( fProbOne )
+ fTrans = 0;
+ vSwitching = Vec_IntStart( Aig_ManObjNumMax(p) );
+ pSwitching = (float *)vSwitching->pArray;
+clk = clock();
+ pAig = Faig_ManCreate( p );
+//PRT( "\nCreation ", 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 = clock();
+ pProbs = Faig_ManSimulateFrames( pAig, nFramesReal, nPref, fTrans );
+//PRT( "Simulation", clock() - clk );
+clk = 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_ManForEachPi( 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_ManForEachPo( 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_ManForEachPi( 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_ManForEachPo( 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_ManForEachPi( 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_ManForEachPo( p, pObj, i )
+ pSwitching[pObj->Id] = Faig_ManComputeSwitching( pProbs[Counter++], nFramesReal - nPref );
+ assert( Counter == pAig->nObjs );
+ }
+ free( pProbs );
+ free( pAig );
+//PRT( "Switch ", clock() - clk );
+//PRT( "TOTAL ", clock() - clkTotal );
+ return vSwitching;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes probability of switching (or of being 1).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
+{
+ return Faig_ManComputeSwitchProbs( p, nFrames, nPref, fProbOne );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+