| /**CFile**************************************************************** |
| |
| FileName [covMinEsop.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Mapping into network of SOPs/ESOPs.] |
| |
| Synopsis [ESOP manipulation.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: covMinEsop.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "covInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static void Min_EsopRewrite( Min_Man_t * p ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Min_EsopMinimize( Min_Man_t * p ) |
| { |
| int nCubesInit, nCubesOld, nIter; |
| if ( p->nCubes < 3 ) |
| return; |
| nIter = 0; |
| nCubesInit = p->nCubes; |
| do { |
| nCubesOld = p->nCubes; |
| Min_EsopRewrite( p ); |
| nIter++; |
| } |
| while ( 100.0*(nCubesOld - p->nCubes)/nCubesOld > 3.0 ); |
| |
| // printf( "%d:%d->%d ", nIter, nCubesInit, p->nCubes ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs one round of rewriting using distance 2 cubes.] |
| |
| Description [The weakness of this procedure is that it tries each cube |
| with only one distance-2 cube. If this pair does not lead to improvement |
| the cube is inserted into the cover anyhow, and we try another pair. |
| A possible improvement would be to try this cube with all distance-2 |
| cubes, until an improvement is found, or until all such cubes are tried.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Min_EsopRewrite( Min_Man_t * p ) |
| { |
| Min_Cube_t * pCube, ** ppPrev; |
| Min_Cube_t * pThis, ** ppPrevT; |
| int v00, v01, v10, v11, Var0, Var1, Index, nCubesOld; |
| int nPairs = 0; |
| |
| // insert the bubble before the first cube |
| p->pBubble->pNext = p->ppStore[0]; |
| p->ppStore[0] = p->pBubble; |
| p->pBubble->nLits = 0; |
| |
| // go through the cubes |
| while ( 1 ) |
| { |
| // get the index of the bubble |
| Index = p->pBubble->nLits; |
| |
| // find the bubble |
| Min_CoverForEachCubePrev( p->ppStore[Index], pCube, ppPrev ) |
| if ( pCube == p->pBubble ) |
| break; |
| assert( pCube == p->pBubble ); |
| |
| // remove the bubble, get the next cube after the bubble |
| *ppPrev = p->pBubble->pNext; |
| pCube = p->pBubble->pNext; |
| if ( pCube == NULL ) |
| for ( Index++; Index <= p->nVars; Index++ ) |
| if ( p->ppStore[Index] ) |
| { |
| ppPrev = &(p->ppStore[Index]); |
| pCube = p->ppStore[Index]; |
| break; |
| } |
| // stop if there is no more cubes |
| if ( pCube == NULL ) |
| break; |
| |
| // find the first dist2 cube |
| Min_CoverForEachCubePrev( pCube->pNext, pThis, ppPrevT ) |
| if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) |
| break; |
| if ( pThis == NULL && Index < p->nVars ) |
| Min_CoverForEachCubePrev( p->ppStore[Index+1], pThis, ppPrevT ) |
| if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) |
| break; |
| if ( pThis == NULL && Index < p->nVars - 1 ) |
| Min_CoverForEachCubePrev( p->ppStore[Index+2], pThis, ppPrevT ) |
| if ( Min_CubesDistTwo( pCube, pThis, &Var0, &Var1 ) ) |
| break; |
| // continue if there is no dist2 cube |
| if ( pThis == NULL ) |
| { |
| // insert the bubble after the cube |
| p->pBubble->pNext = pCube->pNext; |
| pCube->pNext = p->pBubble; |
| p->pBubble->nLits = pCube->nLits; |
| continue; |
| } |
| nPairs++; |
| |
| // remove the cubes, insert the bubble instead of pCube |
| *ppPrevT = pThis->pNext; |
| *ppPrev = p->pBubble; |
| p->pBubble->pNext = pCube->pNext; |
| p->pBubble->nLits = pCube->nLits; |
| p->nCubes -= 2; |
| |
| // Exorlink-2: |
| // A{v00} B{v01} + A{v10} B{v11} = |
| // A{v00+v10} B{v01} + A{v10} B{v01+v11} = |
| // A{v00} B{v01+v11} + A{v00+v10} B{v11} |
| |
| // save the dist2 parameters |
| v00 = Min_CubeGetVar( pCube, Var0 ); |
| v01 = Min_CubeGetVar( pCube, Var1 ); |
| v10 = Min_CubeGetVar( pThis, Var0 ); |
| v11 = Min_CubeGetVar( pThis, Var1 ); |
| //printf( "\n" ); |
| //Min_CubeWrite( stdout, pCube ); |
| //Min_CubeWrite( stdout, pThis ); |
| |
| // derive the first pair of resulting cubes |
| Min_CubeXorVar( pCube, Var0, v10 ); |
| pCube->nLits -= (v00 != 3); |
| pCube->nLits += ((v00 ^ v10) != 3); |
| Min_CubeXorVar( pThis, Var1, v01 ); |
| pThis->nLits -= (v11 != 3); |
| pThis->nLits += ((v01 ^ v11) != 3); |
| |
| // add the cubes |
| nCubesOld = p->nCubes; |
| Min_EsopAddCube( p, pCube ); |
| Min_EsopAddCube( p, pThis ); |
| // check if the cubes were absorbed |
| if ( p->nCubes < nCubesOld + 2 ) |
| continue; |
| |
| // pull out both cubes |
| assert( pThis == p->ppStore[pThis->nLits] ); |
| p->ppStore[pThis->nLits] = pThis->pNext; |
| assert( pCube == p->ppStore[pCube->nLits] ); |
| p->ppStore[pCube->nLits] = pCube->pNext; |
| p->nCubes -= 2; |
| |
| // derive the second pair of resulting cubes |
| Min_CubeXorVar( pCube, Var0, v10 ); |
| pCube->nLits -= ((v00 ^ v10) != 3); |
| pCube->nLits += (v00 != 3); |
| Min_CubeXorVar( pCube, Var1, v11 ); |
| pCube->nLits -= (v01 != 3); |
| pCube->nLits += ((v01 ^ v11) != 3); |
| |
| Min_CubeXorVar( pThis, Var0, v00 ); |
| pThis->nLits -= (v10 != 3); |
| pThis->nLits += ((v00 ^ v10) != 3); |
| Min_CubeXorVar( pThis, Var1, v01 ); |
| pThis->nLits -= ((v01 ^ v11) != 3); |
| pThis->nLits += (v11 != 3); |
| |
| // add them anyhow |
| Min_EsopAddCube( p, pCube ); |
| Min_EsopAddCube( p, pThis ); |
| } |
| // printf( "Pairs = %d ", nPairs ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Adds the cube to storage.] |
| |
| Description [Returns 0 if the cube is added or removed. Returns 1 |
| if the cube is glued with some other cube and has to be added again. |
| Do not forget to clean the storage!] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Min_EsopAddCubeInt( Min_Man_t * p, Min_Cube_t * pCube ) |
| { |
| Min_Cube_t * pThis, ** ppPrev; |
| // try to find the identical cube |
| Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) |
| { |
| if ( Min_CubesAreEqual( pCube, pThis ) ) |
| { |
| *ppPrev = pThis->pNext; |
| Min_CubeRecycle( p, pCube ); |
| Min_CubeRecycle( p, pThis ); |
| p->nCubes--; |
| return 0; |
| } |
| } |
| // find a distance-1 cube if it exists |
| if ( pCube->nLits < pCube->nVars ) |
| Min_CoverForEachCubePrev( p->ppStore[pCube->nLits+1], pThis, ppPrev ) |
| { |
| if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) |
| { |
| *ppPrev = pThis->pNext; |
| Min_CubesTransform( pCube, pThis, p->pTemp ); |
| pCube->nLits++; |
| Min_CubeRecycle( p, pThis ); |
| p->nCubes--; |
| return 1; |
| } |
| } |
| Min_CoverForEachCubePrev( p->ppStore[pCube->nLits], pThis, ppPrev ) |
| { |
| if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) |
| { |
| *ppPrev = pThis->pNext; |
| Min_CubesTransform( pCube, pThis, p->pTemp ); |
| pCube->nLits--; |
| Min_CubeRecycle( p, pThis ); |
| p->nCubes--; |
| return 1; |
| } |
| } |
| if ( pCube->nLits > 0 ) |
| Min_CoverForEachCubePrev( p->ppStore[pCube->nLits-1], pThis, ppPrev ) |
| { |
| if ( Min_CubesDistOne( pCube, pThis, p->pTemp ) ) |
| { |
| *ppPrev = pThis->pNext; |
| Min_CubesTransform( pCube, pThis, p->pTemp ); |
| Min_CubeRecycle( p, pThis ); |
| p->nCubes--; |
| return 1; |
| } |
| } |
| // add the cube |
| pCube->pNext = p->ppStore[pCube->nLits]; |
| p->ppStore[pCube->nLits] = pCube; |
| p->nCubes++; |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Adds the cube to storage.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ) |
| { |
| assert( pCube != p->pBubble ); |
| assert( (int)pCube->nLits == Min_CubeCountLits(pCube) ); |
| while ( Min_EsopAddCubeInt( p, pCube ) ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |