diff options
Diffstat (limited to 'src/aig/fsim/fsimFront.c')
-rw-r--r-- | src/aig/fsim/fsimFront.c | 364 |
1 files changed, 364 insertions, 0 deletions
diff --git a/src/aig/fsim/fsimFront.c b/src/aig/fsim/fsimFront.c new file mode 100644 index 00000000..d40b1c6f --- /dev/null +++ b/src/aig/fsim/fsimFront.c @@ -0,0 +1,364 @@ +/**CFile**************************************************************** + + FileName [fsimFront.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Fast sequential AIG simulator.] + + Synopsis [Simulation frontier.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: fsimFront.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "fsimInt.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Fsim_ManStoreNum( Fsim_Man_t * p, int Num ) +{ + unsigned x = (unsigned)Num; + assert( Num >= 0 ); + while ( x & ~0x7f ) + { + *p->pDataCur++ = (x & 0x7f) | 0x80; + x >>= 7; + } + *p->pDataCur++ = x; + assert( p->pDataCur - p->pDataAig < p->nDataAig ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Fsim_ManRestoreNum( Fsim_Man_t * p ) +{ + int ch, i, x = 0; + for ( i = 0; (ch = *p->pDataCur++) & 0x80; i++ ) + x |= (ch & 0x7f) << (7 * i); + assert( p->pDataCur - p->pDataAig < p->nDataAig ); + return x | (ch << (7 * i)); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Fsim_ManStoreObj( Fsim_Man_t * p, Fsim_Obj_t * pObj ) +{ + if ( p->pDataAig2 ) + { + *p->pDataCur2++ = pObj->iNode; + *p->pDataCur2++ = pObj->iFan0; + *p->pDataCur2++ = pObj->iFan1; + return; + } + if ( pObj->iFan0 && pObj->iFan1 ) // and + { + assert( pObj->iNode ); + assert( pObj->iNode >= p->iNodePrev ); + assert( (pObj->iNode << 1) > pObj->iFan0 ); + assert( pObj->iFan0 > pObj->iFan1 ); + Fsim_ManStoreNum( p, ((pObj->iNode - p->iNodePrev) << 2) | 3 ); + Fsim_ManStoreNum( p, (pObj->iNode << 1) - pObj->iFan0 ); + Fsim_ManStoreNum( p, pObj->iFan0 - pObj->iFan1 ); + p->iNodePrev = pObj->iNode; + } + else if ( !pObj->iFan0 && !pObj->iFan1 ) // ci + { + assert( pObj->iNode ); + assert( pObj->iNode >= p->iNodePrev ); + Fsim_ManStoreNum( p, ((pObj->iNode - p->iNodePrev) << 2) | 1 ); + p->iNodePrev = pObj->iNode; + } + else // if ( !pObj->iFan0 && pObj->iFan1 ) // co + { + assert( pObj->iNode == 0 ); + assert( pObj->iFan0 != 0 ); + assert( pObj->iFan1 == 0 ); + assert( ((p->iNodePrev << 1) | 1) >= pObj->iFan0 ); + Fsim_ManStoreNum( p, (((p->iNodePrev << 1) | 1) - pObj->iFan0) << 1 ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Fsim_ManRestoreObj( Fsim_Man_t * p, Fsim_Obj_t * pObj ) +{ + int iValue = Fsim_ManRestoreNum( p ); + if ( (iValue & 3) == 3 ) // and + { + pObj->iNode = (iValue >> 2) + p->iNodePrev; + pObj->iFan0 = (pObj->iNode << 1) - Fsim_ManRestoreNum( p ); + pObj->iFan1 = pObj->iFan0 - Fsim_ManRestoreNum( p ); + p->iNodePrev = pObj->iNode; + } + else if ( (iValue & 3) == 1 ) // ci + { + pObj->iNode = (iValue >> 2) + p->iNodePrev; + pObj->iFan0 = 0; + pObj->iFan1 = 0; + p->iNodePrev = pObj->iNode; + } + else // if ( (iValue & 1) == 0 ) // co + { + pObj->iNode = 0; + pObj->iFan0 = ((p->iNodePrev << 1) | 1) - (iValue >> 1); + pObj->iFan1 = 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Determine the frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Fsim_ManFrontFindNext( Fsim_Man_t * p, char * pFront ) +{ + assert( p->iNumber < (1 << 30) - p->nFront ); + while ( 1 ) + { + if ( p->iNumber % p->nFront == 0 ) + p->iNumber++; + if ( pFront[p->iNumber % p->nFront] == 0 ) + { + pFront[p->iNumber % p->nFront] = 1; + return p->iNumber; + } + p->iNumber++; + } + return -1; +} + +/**Function************************************************************* + + Synopsis [Verifies the frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fsim_ManVerifyFront( Fsim_Man_t * p ) +{ + Fsim_Obj_t * pObj; + int * pFans0, * pFans1; // representation of fanins + int * pFrontToId; // mapping of nodes into frontier variables + int i, iVar0, iVar1; + pFans0 = ALLOC( int, p->nObjs ); + pFans1 = ALLOC( int, p->nObjs ); + pFans0[0] = pFans1[0] = 0; + pFans0[1] = pFans1[1] = 0; + pFrontToId = CALLOC( int, p->nFront ); + if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) ) + pFrontToId[1] = 1; + Fsim_ManForEachObj( p, pObj, i ) + { + if ( pObj->iNode ) + pFrontToId[pObj->iNode % p->nFront] = i; + iVar0 = Fsim_Lit2Var(pObj->iFan0); + iVar1 = Fsim_Lit2Var(pObj->iFan1); + pFans0[i] = Fsim_Var2Lit(pFrontToId[iVar0 % p->nFront], Fsim_LitIsCompl(pObj->iFan0)); + pFans1[i] = Fsim_Var2Lit(pFrontToId[iVar1 % p->nFront], Fsim_LitIsCompl(pObj->iFan1)); + } + for ( i = 0; i < p->nObjs; i++ ) + { + assert( pFans0[i] == p->pFans0[i] ); + assert( pFans1[i] == p->pFans1[i] ); + } + free( pFrontToId ); + free( pFans0 ); + free( pFans1 ); +} + +/**Function************************************************************* + + Synopsis [Determine the frontier.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Fsim_ManFront( Fsim_Man_t * p, int fCompressAig ) +{ + Fsim_Obj_t Obj, * pObj = &Obj; + char * pFront; // places used for the frontier + int * pIdToFront; // mapping of nodes into frontier places + int i, iVar0, iVar1, nCrossCut = 0, nCrossCutMax = 0; + // start the frontier + pFront = CALLOC( char, p->nFront ); + pIdToFront = ALLOC( int, p->nObjs ); + pIdToFront[0] = -1; + pIdToFront[1] = -1; + // add constant node + p->iNumber = 1; + if ( p->pRefs[1] ) + { + pIdToFront[1] = Fsim_ManFrontFindNext( p, pFront ); + nCrossCut = 1; + } + // allocate room for data + if ( fCompressAig ) + { + p->nDataAig = p->nObjs * 6; + p->pDataAig = ALLOC( unsigned char, p->nDataAig ); + p->pDataCur = p->pDataAig; + p->iNodePrev = 0; + } + else + { + p->pDataAig2 = ALLOC( int, 3 * p->nObjs ); + p->pDataCur2 = p->pDataAig2 + 6; + } + // iterate through the objects + for ( i = 2; i < p->nObjs; i++ ) + { + if ( p->pFans0[i] == 0 ) // ci + { + // store node + pIdToFront[i] = Fsim_ManFrontFindNext( p, pFront ); + pObj->iNode = pIdToFront[i]; + pObj->iFan0 = 0; + pObj->iFan1 = 0; + Fsim_ManStoreObj( p, pObj ); + // handle CIs without fanout + if ( p->pRefs[i] == 0 ) + { + pFront[pIdToFront[i] % p->nFront] = 0; + pIdToFront[i] = -1; + } + } + else if ( p->pFans1[i] == 0 ) // co + { + assert( p->pRefs[i] == 0 ); + // get the fanin + iVar0 = Fsim_Lit2Var(p->pFans0[i]); + assert( pIdToFront[iVar0] > 0 ); + // store node + pObj->iNode = 0; + pObj->iFan0 = Fsim_Var2Lit(pIdToFront[iVar0], Fsim_LitIsCompl(p->pFans0[i])); + pObj->iFan1 = 0; + Fsim_ManStoreObj( p, pObj ); + // deref the fanin + if ( --p->pRefs[iVar0] == 0 ) + { + pFront[pIdToFront[iVar0] % p->nFront] = 0; + pIdToFront[iVar0] = -1; + nCrossCut--; + } + } + else + { + // get the fanins + iVar0 = Fsim_Lit2Var(p->pFans0[i]); + assert( pIdToFront[iVar0] > 0 ); + iVar1 = Fsim_Lit2Var(p->pFans1[i]); + assert( pIdToFront[iVar1] > 0 ); + // store node + pIdToFront[i] = Fsim_ManFrontFindNext( p, pFront ); + pObj->iNode = pIdToFront[i]; + pObj->iFan0 = Fsim_Var2Lit(pIdToFront[iVar0], Fsim_LitIsCompl(p->pFans0[i])); + pObj->iFan1 = Fsim_Var2Lit(pIdToFront[iVar1], Fsim_LitIsCompl(p->pFans1[i])); + Fsim_ManStoreObj( p, pObj ); + // deref the fanins + if ( --p->pRefs[iVar0] == 0 ) + { + pFront[pIdToFront[iVar0] % p->nFront] = 0; + pIdToFront[iVar0] = -1; + nCrossCut--; + } + if ( --p->pRefs[iVar1] == 0 ) + { + pFront[pIdToFront[iVar1] % p->nFront] = 0; + pIdToFront[iVar1] = -1; + nCrossCut--; + } + // handle nodes without fanout (choice nodes) + if ( p->pRefs[i] == 0 ) + { + pFront[pIdToFront[i] % p->nFront] = 0; + pIdToFront[i] = -1; + } + } + if ( p->pRefs[i] ) + if ( nCrossCutMax < ++nCrossCut ) + nCrossCutMax = nCrossCut; + } + assert( p->pDataAig2 == NULL || p->pDataCur2 - p->pDataAig2 == (3 * p->nObjs) ); + assert( nCrossCut == 0 ); + assert( nCrossCutMax == p->nCrossCutMax ); + for ( i = 0; i < p->nFront; i++ ) + assert( pFront[i] == 0 ); + free( pFront ); + free( pIdToFront ); +// Fsim_ManVerifyFront( p ); + FREE( p->pFans0 ); + FREE( p->pFans1 ); + FREE( p->pRefs ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |