summaryrefslogtreecommitdiffstats
path: root/src/aig/fsim/fsimFront.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2009-01-18 08:01:00 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2009-01-18 08:01:00 -0800
commitf936cc0680c98ffe51b3a1716c996072d5dbf76c (patch)
tree784a2a809fb6b972ec6a8e2758ab758ca590d01a /src/aig/fsim/fsimFront.c
parentc9ad5880cc61787dec6d018111b63023407ce0e6 (diff)
downloadabc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.tar.gz
abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.tar.bz2
abc-f936cc0680c98ffe51b3a1716c996072d5dbf76c.zip
Version abc90118
Diffstat (limited to 'src/aig/fsim/fsimFront.c')
-rw-r--r--src/aig/fsim/fsimFront.c364
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 ///
+////////////////////////////////////////////////////////////////////////
+
+