| /**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" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// 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 = ABC_ALLOC( int, p->nObjs ); |
| pFans1 = ABC_ALLOC( int, p->nObjs ); |
| pFans0[0] = pFans1[0] = 0; |
| pFans0[1] = pFans1[1] = 0; |
| pFrontToId = ABC_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] ); |
| } |
| ABC_FREE( pFrontToId ); |
| ABC_FREE( pFans0 ); |
| ABC_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 = ABC_CALLOC( char, p->nFront ); |
| pIdToFront = ABC_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 = ABC_ALLOC( unsigned char, p->nDataAig ); |
| p->pDataCur = p->pDataAig; |
| p->iNodePrev = 0; |
| } |
| else |
| { |
| p->pDataAig2 = ABC_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 ); |
| ABC_FREE( pFront ); |
| ABC_FREE( pIdToFront ); |
| // Fsim_ManVerifyFront( p ); |
| ABC_FREE( p->pFans0 ); |
| ABC_FREE( p->pFans1 ); |
| ABC_FREE( p->pRefs ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |