/src/base/abci/abcExtract.c
C | 752 lines | 548 code | 62 blank | 142 comment | 89 complexity | 5e2f0c7cdfd3d60ddf6910b8bd82d68f MD5 | raw file
Possible License(s): BSD-3-Clause
- /**CFile****************************************************************
-
- FileName [abcShare.c]
-
- SystemName [ABC: Logic synthesis and verification system.]
-
- PackageName [Network and node package.]
-
- Synopsis [Shared logic extraction.]
-
- Author [Alan Mishchenko]
-
- Affiliation [UC Berkeley]
-
- Date [Ver. 1.0. Started - June 20, 2005.]
-
- Revision [$Id: abcShare.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
- ***********************************************************************/
-
- #include "base/abc/abc.h"
-
- ABC_NAMESPACE_IMPL_START
-
- ////////////////////////////////////////////////////////////////////////
- /// DECLARATIONS ///
- ////////////////////////////////////////////////////////////////////////
-
- #define SHARE_NUM 2
-
- typedef struct Abc_ShaMan_t_ Abc_ShaMan_t;
- struct Abc_ShaMan_t_
- {
- int nMultiSize;
- int fVerbose;
- Abc_Ntk_t * pNtk;
- Vec_Ptr_t * vBuckets;
- Vec_Int_t * vObj2Lit;
- int nStartCols;
- int nCountGates;
- int nFoundGates;
- };
-
- static inline word Abc_NtkSharePack( int Lev, int Id ) { return (((word)Lev) << 32) | Id; }
- static inline int Abc_NtkShareUnpackLev( word Num ) { return (Num >> 32); }
- static inline int Abc_NtkShareUnpackId( word Num ) { return Num & 0xFFFFFFFF; }
-
-
- ////////////////////////////////////////////////////////////////////////
- /// FUNCTION DEFINITIONS ///
- ////////////////////////////////////////////////////////////////////////
-
- /**Function*************************************************************
-
- Synopsis [Working with the manager.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- Abc_ShaMan_t * Abc_ShaManStart( Abc_Ntk_t * pNtk )
- {
- Abc_ShaMan_t * p;
- p = ABC_CALLOC( Abc_ShaMan_t, 1 );
- p->pNtk = pNtk;
- p->vObj2Lit = Vec_IntAlloc( 1000 );
- return p;
- }
- void Abc_ShaManStop( Abc_ShaMan_t * p )
- {
- Vec_Ptr_t * vBucket;
- int i;
- Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
- Vec_VecFree( (Vec_Vec_t *)vBucket );
- Vec_PtrFreeP( &p->vBuckets );
- Vec_IntFreeP( &p->vObj2Lit );
- ABC_FREE( p );
- }
-
-
- /**Function*************************************************************
-
- Synopsis [Collects one multi-input gate.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- Vec_Wrd_t * Abc_NtkShareSuperXor( Abc_Obj_t * pObj, int * pfCompl, int * pCounter )
- {
- Abc_Ntk_t * pNtk = Abc_ObjNtk(pObj);
- Abc_Obj_t * pObjC, * pObj0, * pObj1, * pRoot = NULL;
- Vec_Wrd_t * vSuper;
- word Num, NumNext;
- int i, k, fCompl = 0;
- assert( !Abc_ObjIsComplement(pObj) );
- assert( Abc_NodeIsExorType(pObj) );
- // start iteration
- vSuper = Vec_WrdAlloc( 10 );
- Vec_WrdPush( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObj), Abc_ObjId(pObj)) );
- while ( Vec_WrdSize(vSuper) > 0 )
- {
- // make sure there are no duplicates
- Num = Vec_WrdEntry( vSuper, 0 );
- Vec_WrdForEachEntryStart( vSuper, NumNext, i, 1 )
- {
- assert( Num < NumNext );
- Num = NumNext;
- }
- // extract XOR gate decomposable on the topmost level
- Vec_WrdForEachEntryReverse( vSuper, Num, i )
- {
- pRoot = Abc_NtkObj( pNtk, Abc_NtkShareUnpackId(Num) );
- if ( Abc_NodeIsExorType(pRoot) )
- {
- Vec_WrdRemove( vSuper, Num );
- break;
- }
- }
- if ( i == -1 )
- break;
- // extract
- pObjC = Abc_NodeRecognizeMux( pRoot, &pObj1, &pObj0 );
- assert( pObj1 == Abc_ObjNot(pObj0) );
- fCompl ^= Abc_ObjIsComplement(pObjC); pObjC = Abc_ObjRegular(pObjC);
- fCompl ^= Abc_ObjIsComplement(pObj0); pObj0 = Abc_ObjRegular(pObj0);
- Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObjC), Abc_ObjId(pObjC)) );
- Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObj0), Abc_ObjId(pObj0)) );
- (*pCounter)++;
- // remove duplicates
- k = 0;
- Vec_WrdForEachEntry( vSuper, Num, i )
- {
- if ( i + 1 == Vec_WrdSize(vSuper) )
- {
- Vec_WrdWriteEntry( vSuper, k++, Num );
- break;
- }
- NumNext = Vec_WrdEntry( vSuper, i+1 );
- assert( Num <= NumNext );
- if ( Num == NumNext )
- i++;
- else
- Vec_WrdWriteEntry( vSuper, k++, Num );
- }
- Vec_WrdShrink( vSuper, k );
- }
- *pfCompl = fCompl;
- Vec_WrdForEachEntry( vSuper, Num, i )
- Vec_WrdWriteEntry( vSuper, i, Abc_NtkShareUnpackId(Num) );
- return vSuper;
- }
- Vec_Wrd_t * Abc_NtkShareSuperAnd( Abc_Obj_t * pObj, int * pCounter )
- {
- Abc_Ntk_t * pNtk = Abc_ObjNtk(pObj);
- Abc_Obj_t * pObj0, * pObj1, * pRoot = NULL;
- Vec_Wrd_t * vSuper;
- word Num, NumNext;
- int i, k;
- assert( !Abc_ObjIsComplement(pObj) );
- // start iteration
- vSuper = Vec_WrdAlloc( 10 );
- Vec_WrdPush( vSuper, Abc_NtkSharePack(Abc_ObjLevel(pObj), Abc_ObjToLit(pObj)) );
- while ( Vec_WrdSize(vSuper) > 0 )
- {
- // make sure there are no duplicates
- Num = Vec_WrdEntry( vSuper, 0 );
- Vec_WrdForEachEntryStart( vSuper, NumNext, i, 1 )
- {
- assert( Num < NumNext );
- Num = NumNext;
- }
- // extract AND gate decomposable on the topmost level
- Vec_WrdForEachEntryReverse( vSuper, Num, i )
- {
- pRoot = Abc_ObjFromLit( pNtk, Abc_NtkShareUnpackId(Num) );
- if ( !Abc_ObjIsComplement(pRoot) && Abc_ObjIsNode(pRoot) )
- {
- Vec_WrdRemove( vSuper, Num );
- break;
- }
- }
- if ( i == -1 )
- break;
- assert( Abc_ObjIsNode(pRoot) );
- // extract
- pObj0 = Abc_ObjChild0(pRoot);
- pObj1 = Abc_ObjChild1(pRoot);
- assert( Abc_ObjIsNode(Abc_ObjRegular(pObj0)) || Abc_ObjIsCi(Abc_ObjRegular(pObj0)) );
- assert( Abc_ObjIsNode(Abc_ObjRegular(pObj1)) || Abc_ObjIsCi(Abc_ObjRegular(pObj1)) );
- Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(Abc_ObjRegular(pObj0)), Abc_ObjToLit(pObj0)) );
- Vec_WrdPushOrder( vSuper, Abc_NtkSharePack(Abc_ObjLevel(Abc_ObjRegular(pObj1)), Abc_ObjToLit(pObj1)) );
- (*pCounter)++;
- // remove duplicates
- k = 0;
- Vec_WrdForEachEntry( vSuper, Num, i )
- {
- if ( i + 1 == Vec_WrdSize(vSuper) )
- {
- Vec_WrdWriteEntry( vSuper, k++, Num );
- break;
- }
- NumNext = Vec_WrdEntry( vSuper, i+1 );
- assert( Num <= NumNext );
- if ( Num + 1 == NumNext && (NumNext & 1) ) // pos_lit & neg_lit = 0
- {
- Vec_WrdClear( vSuper );
- return vSuper;
- }
- if ( Num < NumNext )
- Vec_WrdWriteEntry( vSuper, k++, Num );
- }
- Vec_WrdShrink( vSuper, k );
- }
- Vec_WrdForEachEntry( vSuper, Num, i )
- Vec_WrdWriteEntry( vSuper, i, Abc_NtkShareUnpackId(Num) );
- return vSuper;
- }
-
- /**Function*************************************************************
-
- Synopsis [Creates multi-input XOR representation for the nodes.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- void Abc_NtkTraverseSupersXor_rec( Abc_ShaMan_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vInputs )
- {
- if ( Abc_NodeIsTravIdCurrent( pObj ) )
- return;
- Abc_NodeSetTravIdCurrent( pObj );
- if ( Abc_ObjIsCi(pObj) )
- return;
- assert( Abc_ObjIsNode(pObj) );
- if ( Abc_NodeIsExorType(pObj) )
- {
- Vec_Wrd_t * vSuper;
- int k, fCompl;
- word Num;
- vSuper = Abc_NtkShareSuperXor( pObj, &fCompl, &p->nFoundGates );
- if ( Vec_WrdSize(vSuper) <= 1 || Vec_WrdSize(vSuper) >= p->nMultiSize )
- {
- Vec_WrdForEachEntry( vSuper, Num, k )
- {
- Vec_Int_t * vInput = (Vec_Int_t *)Vec_PtrEntry( vInputs, (int)Num );
- if ( vInput == NULL )
- {
- vInput = Vec_IntAlloc( 10 );
- Vec_IntPush( vInput, Abc_Var2Lit((int)Num, 0) );
- Vec_IntPush( vInput, Abc_ObjLevel(Abc_NtkObj(p->pNtk, (int)Num)) );
- assert( SHARE_NUM == Vec_IntSize(vInput) );
- Vec_PtrWriteEntry( vInputs, (int)Num, vInput );
- }
- Vec_IntPush( vInput, Vec_IntSize(p->vObj2Lit) );
- }
- Vec_IntPush( p->vObj2Lit, Abc_Var2Lit(Abc_ObjId(pObj), fCompl) );
- }
- // call recursively
- Vec_WrdForEachEntry( vSuper, Num, k )
- Abc_NtkTraverseSupersXor_rec( p, Abc_NtkObj(p->pNtk, (int)Num), vInputs );
- Vec_WrdFree( vSuper );
- }
- else
- {
- Abc_NtkTraverseSupersXor_rec( p, Abc_ObjFanin0(pObj), vInputs );
- Abc_NtkTraverseSupersXor_rec( p, Abc_ObjFanin1(pObj), vInputs );
- }
- }
- void Abc_NtkTraverseSupersAnd_rec( Abc_ShaMan_t * p, Abc_Obj_t * pObj, Vec_Ptr_t * vInputs )
- {
- Vec_Wrd_t * vSuper;
- word Num;
- int k;
- if ( Abc_NodeIsTravIdCurrent( pObj ) )
- return;
- Abc_NodeSetTravIdCurrent( pObj );
- if ( Abc_ObjIsCi(pObj) )
- return;
- assert( Abc_ObjIsNode(pObj) );
- vSuper = Abc_NtkShareSuperAnd( pObj, &p->nFoundGates );
- if ( Vec_WrdSize(vSuper) <= 1 || Vec_WrdSize(vSuper) >= p->nMultiSize )
- {
- Vec_WrdForEachEntry( vSuper, Num, k )
- {
- Vec_Int_t * vInput = (Vec_Int_t *)Vec_PtrEntry( vInputs, (int)Num );
- if ( vInput == NULL )
- {
- vInput = Vec_IntAlloc( 10 );
- Vec_IntPush( vInput, (int)Num );
- Vec_IntPush( vInput, Abc_ObjLevel(Abc_NtkObj(p->pNtk, Abc_Lit2Var((int)Num))) );
- assert( SHARE_NUM == Vec_IntSize(vInput) );
- Vec_PtrWriteEntry( vInputs, (int)Num, vInput );
- }
- Vec_IntPush( vInput, Vec_IntSize(p->vObj2Lit) );
- }
- Vec_IntPush( p->vObj2Lit, Abc_ObjToLit(pObj) );
- }
- // call recursively
- Vec_WrdForEachEntry( vSuper, Num, k )
- Abc_NtkTraverseSupersAnd_rec( p, Abc_NtkObj(p->pNtk, Abc_Lit2Var((int)Num)), vInputs );
- Vec_WrdFree( vSuper );
- }
- void Abc_NtkTraverseSupers( Abc_ShaMan_t * p, int fAnd )
- {
- Vec_Ptr_t * vInputs;
- Vec_Int_t * vInput;
- Abc_Obj_t * pObj;
- int i, nOnesMax;
-
- // create mapping of nodes into their column vectors
- vInputs = Vec_PtrStart( Abc_NtkObjNumMax(p->pNtk) * (1 + fAnd) );
- Abc_NtkIncrementTravId( p->pNtk );
- if ( fAnd )
- {
- Abc_NtkForEachCo( p->pNtk, pObj, i )
- if ( Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
- Abc_NtkTraverseSupersAnd_rec( p, Abc_ObjFanin0(pObj), vInputs );
- }
- else
- {
- Abc_NtkForEachCo( p->pNtk, pObj, i )
- if ( Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
- Abc_NtkTraverseSupersXor_rec( p, Abc_ObjFanin0(pObj), vInputs );
- }
- p->nStartCols = Vec_IntSize(p->vObj2Lit);
-
- // find the largest number of 1s
- nOnesMax = 0;
- Vec_PtrForEachEntry( Vec_Int_t *, vInputs, vInput, i )
- if ( vInput )
- nOnesMax = Abc_MaxInt( nOnesMax, Vec_IntSize(vInput)-SHARE_NUM );
-
- // create buckets
- assert( p->vBuckets == NULL );
- p->vBuckets = Vec_PtrAlloc( nOnesMax + 1 );
- for ( i = 0; i <= nOnesMax; i++ )
- Vec_PtrPush( p->vBuckets, Vec_PtrAlloc(10) );
-
- // load vectors into buckets
- Vec_PtrForEachEntry( Vec_Int_t *, vInputs, vInput, i )
- if ( vInput )
- Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vInput)-SHARE_NUM), vInput );
- Vec_PtrFree( vInputs );
- }
-
- /**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- void Abc_NtkSharePrint( Abc_ShaMan_t * p )
- {
- Vec_Ptr_t * vBucket;
- Vec_Int_t * vInput;
- int i, k, j, ObjId;
- char * pBuffer = ABC_ALLOC( char, Vec_IntSize(p->vObj2Lit) + 1 );
- int * pCounters = ABC_CALLOC( int, Vec_IntSize(p->vObj2Lit) + 1 );
- int nTotal = 0;
- Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
- Vec_PtrForEachEntry( Vec_Int_t *, vBucket, vInput, j )
- {
- for ( k = 0; k < Vec_IntSize(p->vObj2Lit); k++ )
- pBuffer[k] = '0';
- pBuffer[k] = 0;
-
- Vec_IntForEachEntryStart( vInput, ObjId, k, SHARE_NUM )
- {
- assert( ObjId < Vec_IntSize(p->vObj2Lit) );
- pBuffer[ObjId] = '1';
- pCounters[ObjId]++;
- }
- printf( "%4d%3d: %s\n", Vec_IntEntry(vInput, 0), Vec_IntEntry(vInput, 1), pBuffer );
- }
-
- for ( i = 0; i < Vec_IntSize(p->vObj2Lit); i++ )
- if ( pCounters[i] > 0 )
- printf( "%d=%d ", i, pCounters[i] );
- printf( "\n" );
-
- nTotal = 0;
- for ( i = 0; i < p->nStartCols; i++ )
- nTotal += pCounters[i] - 1;
- printf( "Total = %d. ", nTotal );
- printf( "Gates = %d.\n", Vec_IntSize(p->vObj2Lit) - p->nStartCols + nTotal );
-
- ABC_FREE( pCounters );
- ABC_FREE( pBuffer );
-
- printf( "Bucket contents: " );
- Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
- printf( "%d ", Vec_PtrSize(vBucket) );
- printf( "\n" );
- }
-
- /**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- void Abc_NtkDumpBlif( Abc_Ntk_t * p )
- {
- FILE * pFile;
- Vec_Ptr_t * vSupp;
- Abc_Obj_t * pObj;
- int i, k;
- pFile = fopen( "multi_and.blif", "wb" );
- if ( pFile == NULL )
- {
- printf( "Cannot open output file.\n" );
- return;
- }
- fprintf( pFile, ".model %s\n", "multi_and" );
- fprintf( pFile, ".inputs" );
- for ( i = 0; i < Abc_NtkCiNum(p); i++ )
- fprintf( pFile, " i%d", i );
- fprintf( pFile, "\n" );
- fprintf( pFile, ".outputs" );
- for ( i = 0; i < Abc_NtkCoNum(p); i++ )
- fprintf( pFile, " o%d", i );
- fprintf( pFile, "\n" );
- Abc_NtkForEachCi( p, pObj, i )
- pObj->iTemp = i;
- for ( i = 0; i < Abc_NtkCoNum(p); i++ )
- {
- pObj = Abc_NtkCo( p, i );
- vSupp = Abc_NtkNodeSupport( p, &pObj, 1 );
- fprintf( pFile, ".names" );
- Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, k )
- fprintf( pFile, " i%d", pObj->iTemp );
- fprintf( pFile, " o%d\n", i );
- Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, k )
- fprintf( pFile, "1" );
- fprintf( pFile, " 1\n" );
- Vec_PtrFree( vSupp );
- }
- fprintf( pFile, ".end\n\n" );
- fclose( pFile );
- }
-
-
- /**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- void Abc_NtkShareFindBestMatch( Vec_Ptr_t * vBuckets, Vec_Int_t ** pvInput, Vec_Int_t ** pvInput2 )
- {
- int nPoolSize = 40;
- Vec_Ptr_t * vPool = Vec_PtrAlloc( nPoolSize );
- Vec_Ptr_t * vBucket;
- Vec_Int_t * vInput, * vInput2, * vInputBest = NULL, * vInputBest2 = NULL;
- int i, k, Cost, CostBest = 0, Delay, DelayBest = 0;
-
- Vec_PtrForEachEntryReverse( Vec_Ptr_t *, vBuckets, vBucket, i )
- Vec_PtrForEachEntry( Vec_Int_t *, vBucket, vInput, k )
- {
- Vec_PtrPush( vPool, vInput );
- if ( Vec_PtrSize(vPool) == nPoolSize )
- goto outside;
- }
- outside:
-
- Vec_PtrForEachEntryReverse( Vec_Int_t *, vPool, vInput, i )
- Vec_PtrForEachEntryReverse( Vec_Int_t *, vPool, vInput2, k )
- {
- if ( i == k )
- continue;
-
- vInput->pArray += SHARE_NUM;
- vInput2->pArray += SHARE_NUM;
- vInput->nSize -= SHARE_NUM;
- vInput2->nSize -= SHARE_NUM;
-
- Cost = Vec_IntTwoCountCommon(vInput, vInput2);
-
- vInput->pArray -= SHARE_NUM;
- vInput2->pArray -= SHARE_NUM;
- vInput->nSize += SHARE_NUM;
- vInput2->nSize += SHARE_NUM;
-
- if ( Cost < 2 )
- continue;
-
- Delay = Abc_MaxInt( Vec_IntEntry(vInput, 1), Vec_IntEntry(vInput2, 1) );
-
- if ( CostBest < Cost || (CostBest == Cost && (DelayBest > Delay)) )
- {
- CostBest = Cost;
- DelayBest = Delay;
- vInputBest = vInput;
- vInputBest2 = vInput2;
- }
- }
- Vec_PtrFree( vPool );
-
- *pvInput = vInputBest;
- *pvInput2 = vInputBest2;
-
- if ( vInputBest == NULL )
- return;
-
- Vec_PtrRemove( (Vec_Ptr_t *)Vec_PtrEntry(vBuckets, Vec_IntSize(vInputBest)-SHARE_NUM), (Vec_Int_t *)vInputBest );
- Vec_PtrRemove( (Vec_Ptr_t *)Vec_PtrEntry(vBuckets, Vec_IntSize(vInputBest2)-SHARE_NUM), (Vec_Int_t *)vInputBest2 );
- }
- void Abc_NtkShareOptimize( Abc_ShaMan_t * p, int fAnd )
- {
- Abc_Obj_t * pObj, * pObj0, * pObj1;
- Vec_Int_t * vInput, * vInput2;
- Vec_Int_t * vNew, * vOld1, * vOld2;
- int i;
- for ( i = 0; ; i++ )
- {
- Abc_NtkShareFindBestMatch( p->vBuckets, &vInput, &vInput2 );
- if ( vInput == NULL )
- break;
-
- // create new node
- pObj0 = Abc_ObjFromLit( p->pNtk, Vec_IntEntry(vInput, 0) );
- pObj1 = Abc_ObjFromLit( p->pNtk, Vec_IntEntry(vInput2, 0) );
- if ( fAnd )
- pObj = Abc_AigAnd( (Abc_Aig_t *)p->pNtk->pManFunc, pObj0, pObj1 );
- else
- pObj = Abc_AigXor( (Abc_Aig_t *)p->pNtk->pManFunc, pObj0, pObj1 );
- p->nCountGates++;
-
- // save new node
- vOld1 = Vec_IntAlloc( 16 ); Vec_IntPush( vOld1, Vec_IntEntry(vInput, 0) ); Vec_IntPush( vOld1, Vec_IntEntry(vInput, 1) );
- vOld2 = Vec_IntAlloc( 16 ); Vec_IntPush( vOld2, Vec_IntEntry(vInput2, 0) ); Vec_IntPush( vOld2, Vec_IntEntry(vInput2, 1) );
- vNew = Vec_IntAlloc( 16 ); Vec_IntPush( vNew, Abc_ObjToLit(pObj) ); Vec_IntPush( vNew, Abc_ObjLevel(Abc_ObjRegular(pObj)) );
-
- // compute new arrays
- vInput->pArray += SHARE_NUM;
- vInput2->pArray += SHARE_NUM;
- vInput->nSize -= SHARE_NUM;
- vInput2->nSize -= SHARE_NUM;
-
- Vec_IntTwoSplit( vInput, vInput2, vNew, vOld1, vOld2 );
-
- vInput->pArray -= SHARE_NUM;
- vInput2->pArray -= SHARE_NUM;
- vInput->nSize += SHARE_NUM;
- vInput2->nSize += SHARE_NUM;
-
- // add to the old ones
- Vec_IntPush( vOld1, Vec_IntSize(p->vObj2Lit) );
- Vec_IntPush( vOld2, Vec_IntSize(p->vObj2Lit) );
- Vec_IntPush( p->vObj2Lit, Abc_ObjToLit(pObj) );
-
- Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vOld1)-SHARE_NUM), vOld1 );
- Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vOld2)-SHARE_NUM), vOld2 );
- Vec_PtrPush( (Vec_Ptr_t *)Vec_PtrEntry(p->vBuckets, Vec_IntSize(vNew)-SHARE_NUM), vNew );
-
- Vec_IntFree( vInput );
- Vec_IntFree( vInput2 );
- }
- }
-
- /**Function*************************************************************
-
- Synopsis []
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- Abc_Ntk_t * Abc_NtkUpdateNetwork( Abc_ShaMan_t * p, int fAnd )
- {
- Abc_Ntk_t * pNtk;
- Vec_Int_t * vInput, * vMap2Repl;
- Vec_Ptr_t * vOrig, * vRepl, * vBucket;
- Abc_Obj_t * pObj, * pNew;
- int i, j, k, ObjId, iLit;
- int iLitConst1 = Abc_ObjToLit( Abc_AigConst1(p->pNtk) );
-
- vOrig = Vec_PtrAlloc( p->nStartCols );
- vRepl = Vec_PtrAlloc( p->nStartCols );
- for ( i = 0; i < p->nStartCols; i++ )
- {
- iLit = Vec_IntEntry( p->vObj2Lit, i );
- assert( !fAnd || !Abc_LitIsCompl(iLit) );
-
- pObj = Abc_NtkObj( p->pNtk, Abc_Lit2Var(iLit) );
-
- if ( fAnd )
- pNew = Abc_AigConst1(p->pNtk);
- else
- pNew = Abc_ObjNotCond( Abc_AigConst1(p->pNtk), !Abc_LitIsCompl(iLit) );
-
- Vec_PtrPush( vOrig, pObj );
- Vec_PtrPush( vRepl, pNew );
-
- p->nCountGates--;
- }
-
- // go through the columns
- Vec_PtrForEachEntry( Vec_Ptr_t *, p->vBuckets, vBucket, i )
- Vec_PtrForEachEntry( Vec_Int_t *, vBucket, vInput, j )
- {
- Vec_IntForEachEntryStart( vInput, ObjId, k, SHARE_NUM )
- {
- assert( ObjId < Vec_IntSize(p->vObj2Lit) );
- if ( ObjId >= p->nStartCols )
- break;
- assert( ObjId < p->nStartCols );
- iLit = Vec_IntEntry( vInput, 0 );
-
- pNew = (Abc_Obj_t *)Vec_PtrEntry( vRepl, ObjId );
- if ( fAnd )
- pNew = Abc_AigAnd( (Abc_Aig_t *)p->pNtk->pManFunc, pNew, Abc_ObjFromLit(p->pNtk, iLit) );
- else
- pNew = Abc_AigXor( (Abc_Aig_t *)p->pNtk->pManFunc, pNew, Abc_ObjFromLit(p->pNtk, iLit) );
- Vec_PtrWriteEntry( vRepl, ObjId, pNew );
- p->nCountGates++;
- }
- }
-
- if ( p->fVerbose )
- printf( "Total gates collected = %d. Total gates constructed = %d.\n", p->nFoundGates, p->nCountGates );
-
- // create map of originals
- vMap2Repl = Vec_IntStartFull( Abc_NtkObjNumMax(p->pNtk) );
- Vec_PtrForEachEntry( Abc_Obj_t *, vOrig, pObj, i )
- {
- // printf( "Replacing %d by %d.\n", Abc_ObjId(pObj), Abc_ObjToLit((Abc_Obj_t *)Vec_PtrEntry(vRepl, i)) );
- Vec_IntWriteEntry( vMap2Repl, Abc_ObjId(pObj), Abc_ObjToLit((Abc_Obj_t *)Vec_PtrEntry(vRepl, i)) );
- }
- Vec_PtrFree( vOrig );
- Vec_PtrFree( vRepl );
-
- // update fanin pointers
- Abc_NtkForEachObj( p->pNtk, pObj, i )
- {
- if ( Abc_ObjIsCo(pObj) || Abc_ObjIsNode(pObj) )
- {
- iLit = Vec_IntEntry( vMap2Repl, Abc_ObjFaninId0(pObj) );
- if ( iLit >= 0 )
- {
- if ( iLit == iLitConst1 && fAnd )
- {
- pObj->fCompl0 ^= 1;
- Vec_IntWriteEntry( &pObj->vFanins, 0, Abc_Lit2Var(iLitConst1) );
- }
- else
- {
- pObj->fCompl0 ^= Abc_LitIsCompl(iLit);
- Vec_IntWriteEntry( &pObj->vFanins, 0, Abc_Lit2Var(iLit) );
- }
- }
- }
- if ( Abc_ObjIsNode(pObj) )
- {
- iLit = Vec_IntEntry( vMap2Repl, Abc_ObjFaninId1(pObj) );
- if ( iLit >= 0 )
- {
- if ( iLit == iLitConst1 && fAnd )
- {
- pObj->fCompl1 ^= 1;
- Vec_IntWriteEntry( &pObj->vFanins, 1, Abc_Lit2Var(iLitConst1) );
- }
- else
- {
- pObj->fCompl1 ^= Abc_LitIsCompl(iLit);
- Vec_IntWriteEntry( &pObj->vFanins, 1, Abc_Lit2Var(iLit) );
- }
- }
- }
- }
- Vec_IntFree( vMap2Repl );
-
- // pNtk = Abc_NtkRestrash( p->pNtk, 1 );
- if ( fAnd )
- pNtk = Abc_NtkBalance( p->pNtk, 0, 0, 1 );
- else
- pNtk = Abc_NtkBalanceExor( p->pNtk, 1, 0 );
- return pNtk;
- }
-
- /**Function*************************************************************
-
- Synopsis [Extracts one multi-output XOR.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
- ***********************************************************************/
- Abc_Ntk_t * Abc_NtkShareXor( Abc_Ntk_t * pNtk, int nMultiSize, int fAnd, int fVerbose )
- {
- Abc_Ntk_t * pNtkNew;
- Abc_ShaMan_t * p;
- assert( Abc_NtkIsStrash(pNtk) );
- // Abc_NtkDumpBlif( pNtk );
- p = Abc_ShaManStart( pNtk );
- p->nMultiSize = nMultiSize;
- p->fVerbose = fVerbose;
- Abc_NtkTraverseSupers( p, fAnd );
- if ( p->nStartCols < 2 )
- {
- Abc_ShaManStop( p );
- return Abc_NtkDup( pNtk );
- }
- if ( fVerbose )
- Abc_NtkSharePrint( p );
- Abc_NtkShareOptimize( p, fAnd );
- if ( fVerbose )
- Abc_NtkSharePrint( p );
- pNtkNew = Abc_NtkUpdateNetwork( p, fAnd );
- Abc_ShaManStop( p );
- return pNtkNew;
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- /// END OF FILE ///
- ////////////////////////////////////////////////////////////////////////
-
-
- ABC_NAMESPACE_IMPL_END
-