blob: fef8367533c1abecae28b8388244d611397d76d2 [file] [log] [blame]
/**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