| /**CFile**************************************************************** |
| |
| FileName [covInt.h] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Mapping into network of SOPs/ESOPs.] |
| |
| Synopsis [Internal declarations.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: covInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #ifndef ABC__map__cov__covInt_h |
| #define ABC__map__cov__covInt_h |
| |
| #include "base/abc/abc.h" |
| |
| |
| ABC_NAMESPACE_HEADER_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| typedef struct Min_Man_t_ Min_Man_t; |
| typedef struct Min_Cube_t_ Min_Cube_t; |
| |
| struct Min_Man_t_ |
| { |
| int nVars; // the number of vars |
| int nWords; // the number of words |
| Extra_MmFixed_t * pMemMan; // memory manager for cubes |
| // temporary cubes |
| Min_Cube_t * pOne0; // tautology cube |
| Min_Cube_t * pOne1; // tautology cube |
| Min_Cube_t * pTriv0[2]; // trivial cube |
| Min_Cube_t * pTriv1[2]; // trivial cube |
| Min_Cube_t * pTemp; // cube for computing the distance |
| Min_Cube_t * pBubble; // cube used as a separator |
| // temporary storage for the new cover |
| int nCubes; // the number of cubes |
| Min_Cube_t ** ppStore; // storage for cubes by number of literals |
| }; |
| |
| struct Min_Cube_t_ |
| { |
| Min_Cube_t * pNext; // the pointer to the next cube in the cover |
| unsigned nVars : 10; // the number of variables |
| unsigned nWords : 12; // the number of machine words |
| unsigned nLits : 10; // the number of literals in the cube |
| unsigned uData[1]; // the bit-data for the cube |
| }; |
| |
| |
| // iterators through the entries in the linked lists of cubes |
| #define Min_CoverForEachCube( pCover, pCube ) \ |
| for ( pCube = pCover; \ |
| pCube; \ |
| pCube = pCube->pNext ) |
| #define Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) \ |
| for ( pCube = pCover, \ |
| pCube2 = pCube? pCube->pNext: NULL; \ |
| pCube; \ |
| pCube = pCube2, \ |
| pCube2 = pCube? pCube->pNext: NULL ) |
| #define Min_CoverForEachCubePrev( pCover, pCube, ppPrev ) \ |
| for ( pCube = pCover, \ |
| ppPrev = &(pCover); \ |
| pCube; \ |
| ppPrev = &pCube->pNext, \ |
| pCube = pCube->pNext ) |
| |
| // macros to get hold of bits and values in the cubes |
| static inline int Min_CubeHasBit( Min_Cube_t * p, int i ) { return (p->uData[(i)>>5] & (1<<((i) & 31))) > 0; } |
| static inline void Min_CubeSetBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] |= (1<<((i) & 31)); } |
| static inline void Min_CubeXorBit( Min_Cube_t * p, int i ) { p->uData[(i)>>5] ^= (1<<((i) & 31)); } |
| static inline int Min_CubeGetVar( Min_Cube_t * p, int Var ) { return 3 & (p->uData[(2*Var)>>5] >> ((2*Var) & 31)); } |
| static inline void Min_CubeXorVar( Min_Cube_t * p, int Var, int Value ) { p->uData[(2*Var)>>5] ^= (Value<<((2*Var) & 31)); } |
| |
| /*=== covMinEsop.c ==========================================================*/ |
| extern void Min_EsopMinimize( Min_Man_t * p ); |
| extern void Min_EsopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); |
| /*=== covMinSop.c ==========================================================*/ |
| extern void Min_SopMinimize( Min_Man_t * p ); |
| extern void Min_SopAddCube( Min_Man_t * p, Min_Cube_t * pCube ); |
| /*=== covMinMan.c ==========================================================*/ |
| extern Min_Man_t * Min_ManAlloc( int nVars ); |
| extern void Min_ManClean( Min_Man_t * p, int nSupp ); |
| extern void Min_ManFree( Min_Man_t * p ); |
| /*=== covMinUtil.c ==========================================================*/ |
| extern void Min_CoverCreate( Vec_Str_t * vCover, Min_Cube_t * pCover, char Type ); |
| extern void Min_CubeWrite( FILE * pFile, Min_Cube_t * pCube ); |
| extern void Min_CoverWrite( FILE * pFile, Min_Cube_t * pCover ); |
| extern void Min_CoverWriteStore( FILE * pFile, Min_Man_t * p ); |
| extern void Min_CoverWriteFile( Min_Cube_t * pCover, char * pName, int fEsop ); |
| extern void Min_CoverCheck( Min_Man_t * p ); |
| extern int Min_CubeCheck( Min_Cube_t * pCube ); |
| extern Min_Cube_t * Min_CoverCollect( Min_Man_t * p, int nSuppSize ); |
| extern void Min_CoverExpand( Min_Man_t * p, Min_Cube_t * pCover ); |
| extern int Min_CoverSuppVarNum( Min_Man_t * p, Min_Cube_t * pCover ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates the cube.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline Min_Cube_t * Min_CubeAlloc( Min_Man_t * p ) |
| { |
| Min_Cube_t * pCube; |
| pCube = (Min_Cube_t *)Extra_MmFixedEntryFetch( p->pMemMan ); |
| pCube->pNext = NULL; |
| pCube->nVars = p->nVars; |
| pCube->nWords = p->nWords; |
| pCube->nLits = 0; |
| memset( pCube->uData, 0xff, sizeof(unsigned) * p->nWords ); |
| return pCube; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates the cube representing elementary var.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline Min_Cube_t * Min_CubeAllocVar( Min_Man_t * p, int iVar, int fCompl ) |
| { |
| Min_Cube_t * pCube; |
| pCube = Min_CubeAlloc( p ); |
| Min_CubeXorBit( pCube, iVar*2+fCompl ); |
| pCube->nLits = 1; |
| return pCube; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates the cube.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline Min_Cube_t * Min_CubeDup( Min_Man_t * p, Min_Cube_t * pCopy ) |
| { |
| Min_Cube_t * pCube; |
| pCube = Min_CubeAlloc( p ); |
| memcpy( pCube->uData, pCopy->uData, sizeof(unsigned) * p->nWords ); |
| pCube->nLits = pCopy->nLits; |
| return pCube; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Recycles the cube.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Min_CubeRecycle( Min_Man_t * p, Min_Cube_t * pCube ) |
| { |
| Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Recycles the cube cover.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Min_CoverRecycle( Min_Man_t * p, Min_Cube_t * pCover ) |
| { |
| Min_Cube_t * pCube, * pCube2; |
| Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) |
| Extra_MmFixedEntryRecycle( p->pMemMan, (char *)pCube ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Counts the number of cubes in the cover.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CubeCountLits( Min_Cube_t * pCube ) |
| { |
| unsigned uData; |
| int Count = 0, i, w; |
| for ( w = 0; w < (int)pCube->nWords; w++ ) |
| { |
| uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); |
| for ( i = 0; i < 32; i += 2 ) |
| if ( uData & (1 << i) ) |
| Count++; |
| } |
| return Count; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Counts the number of cubes in the cover.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Min_CubeGetLits( Min_Cube_t * pCube, Vec_Int_t * vLits ) |
| { |
| unsigned uData; |
| int i, w; |
| Vec_IntClear( vLits ); |
| for ( w = 0; w < (int)pCube->nWords; w++ ) |
| { |
| uData = pCube->uData[w] ^ (pCube->uData[w] >> 1); |
| for ( i = 0; i < 32; i += 2 ) |
| if ( uData & (1 << i) ) |
| Vec_IntPush( vLits, w*16 + i/2 ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Counts the number of cubes in the cover.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CoverCountCubes( Min_Cube_t * pCover ) |
| { |
| Min_Cube_t * pCube; |
| int Count = 0; |
| Min_CoverForEachCube( pCover, pCube ) |
| Count++; |
| return Count; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Checks if two cubes are disjoint.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CubesDisjoint( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) |
| { |
| unsigned uData; |
| int i; |
| assert( pCube0->nVars == pCube1->nVars ); |
| for ( i = 0; i < (int)pCube0->nWords; i++ ) |
| { |
| uData = pCube0->uData[i] & pCube1->uData[i]; |
| uData = (uData | (uData >> 1)) & 0x55555555; |
| if ( uData != 0x55555555 ) |
| return 1; |
| } |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Collects the disjoint variables of the two cubes.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Min_CoverGetDisjVars( Min_Cube_t * pThis, Min_Cube_t * pCube, Vec_Int_t * vVars ) |
| { |
| unsigned uData; |
| int i, w; |
| Vec_IntClear( vVars ); |
| for ( w = 0; w < (int)pCube->nWords; w++ ) |
| { |
| uData = pThis->uData[w] & (pThis->uData[w] >> 1) & 0x55555555; |
| uData &= (pCube->uData[w] ^ (pCube->uData[w] >> 1)); |
| if ( uData == 0 ) |
| continue; |
| for ( i = 0; i < 32; i += 2 ) |
| if ( uData & (1 << i) ) |
| Vec_IntPush( vVars, w*16 + i/2 ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Checks if two cubes are disjoint.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CubesDistOne( Min_Cube_t * pCube0, Min_Cube_t * pCube1, Min_Cube_t * pTemp ) |
| { |
| unsigned uData; |
| int i, fFound = 0; |
| for ( i = 0; i < (int)pCube0->nWords; i++ ) |
| { |
| uData = pCube0->uData[i] ^ pCube1->uData[i]; |
| if ( uData == 0 ) |
| { |
| if ( pTemp ) pTemp->uData[i] = 0; |
| continue; |
| } |
| if ( fFound ) |
| return 0; |
| uData = (uData | (uData >> 1)) & 0x55555555; |
| if ( (uData & (uData-1)) > 0 ) // more than one 1 |
| return 0; |
| if ( pTemp ) pTemp->uData[i] = uData | (uData << 1); |
| fFound = 1; |
| } |
| if ( fFound == 0 ) |
| { |
| printf( "\n" ); |
| Min_CubeWrite( stdout, pCube0 ); |
| Min_CubeWrite( stdout, pCube1 ); |
| printf( "Error: Min_CubesDistOne() looks at two equal cubes!\n" ); |
| } |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Checks if two cubes are disjoint.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CubesDistTwo( Min_Cube_t * pCube0, Min_Cube_t * pCube1, int * pVar0, int * pVar1 ) |
| { |
| unsigned uData;//, uData2; |
| int i, k, Var0 = -1, Var1 = -1; |
| for ( i = 0; i < (int)pCube0->nWords; i++ ) |
| { |
| uData = pCube0->uData[i] ^ pCube1->uData[i]; |
| if ( uData == 0 ) |
| continue; |
| if ( Var0 >= 0 && Var1 >= 0 ) // more than two 1s |
| return 0; |
| uData = (uData | (uData >> 1)) & 0x55555555; |
| if ( (Var0 >= 0 || Var1 >= 0) && (uData & (uData-1)) > 0 ) |
| return 0; |
| for ( k = 0; k < 32; k += 2 ) |
| if ( uData & (1 << k) ) |
| { |
| if ( Var0 == -1 ) |
| Var0 = 16 * i + k/2; |
| else if ( Var1 == -1 ) |
| Var1 = 16 * i + k/2; |
| else |
| return 0; |
| } |
| /* |
| if ( Var0 >= 0 ) |
| { |
| uData &= 0xFFFF; |
| uData2 = (uData >> 16); |
| if ( uData && uData2 ) |
| return 0; |
| if ( uData ) |
| { |
| } |
| uData }= uData2; |
| uData &= 0x |
| } |
| */ |
| } |
| if ( Var0 >= 0 && Var1 >= 0 ) |
| { |
| *pVar0 = Var0; |
| *pVar1 = Var1; |
| return 1; |
| } |
| if ( Var0 == -1 || Var1 == -1 ) |
| { |
| printf( "\n" ); |
| Min_CubeWrite( stdout, pCube0 ); |
| Min_CubeWrite( stdout, pCube1 ); |
| printf( "Error: Min_CubesDistTwo() looks at two equal cubes or dist1 cubes!\n" ); |
| } |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Makes the produce of two cubes.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline Min_Cube_t * Min_CubesProduct( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) |
| { |
| Min_Cube_t * pCube; |
| int i; |
| assert( pCube0->nVars == pCube1->nVars ); |
| pCube = Min_CubeAlloc( p ); |
| for ( i = 0; i < p->nWords; i++ ) |
| pCube->uData[i] = pCube0->uData[i] & pCube1->uData[i]; |
| pCube->nLits = Min_CubeCountLits( pCube ); |
| return pCube; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Makes the produce of two cubes.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline Min_Cube_t * Min_CubesXor( Min_Man_t * p, Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) |
| { |
| Min_Cube_t * pCube; |
| int i; |
| assert( pCube0->nVars == pCube1->nVars ); |
| pCube = Min_CubeAlloc( p ); |
| for ( i = 0; i < p->nWords; i++ ) |
| pCube->uData[i] = pCube0->uData[i] ^ pCube1->uData[i]; |
| pCube->nLits = Min_CubeCountLits( pCube ); |
| return pCube; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Makes the produce of two cubes.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CubesAreEqual( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) |
| { |
| int i; |
| for ( i = 0; i < (int)pCube0->nWords; i++ ) |
| if ( pCube0->uData[i] != pCube1->uData[i] ) |
| return 0; |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns 1 if pCube1 is contained in pCube0, bitwise.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CubeIsContained( Min_Cube_t * pCube0, Min_Cube_t * pCube1 ) |
| { |
| int i; |
| for ( i = 0; i < (int)pCube0->nWords; i++ ) |
| if ( (pCube0->uData[i] & pCube1->uData[i]) != pCube1->uData[i] ) |
| return 0; |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transforms the cube into the result of merging.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Min_CubesTransform( Min_Cube_t * pCube, Min_Cube_t * pDist, Min_Cube_t * pMask ) |
| { |
| int w; |
| for ( w = 0; w < (int)pCube->nWords; w++ ) |
| { |
| pCube->uData[w] = pCube->uData[w] ^ pDist->uData[w]; |
| pCube->uData[w] |= (pDist->uData[w] & ~pMask->uData[w]); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transforms the cube into the result of distance-1 merging.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Min_CubesTransformOr( Min_Cube_t * pCube, Min_Cube_t * pDist ) |
| { |
| int w; |
| for ( w = 0; w < (int)pCube->nWords; w++ ) |
| pCube->uData[w] |= pDist->uData[w]; |
| } |
| |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Sorts the cover in the increasing number of literals.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Min_CoverExpandRemoveEqual( Min_Man_t * p, Min_Cube_t * pCover ) |
| { |
| Min_Cube_t * pCube, * pCube2, * pThis; |
| if ( pCover == NULL ) |
| { |
| Min_ManClean( p, p->nVars ); |
| return; |
| } |
| Min_ManClean( p, pCover->nVars ); |
| Min_CoverForEachCubeSafe( pCover, pCube, pCube2 ) |
| { |
| // go through the linked list |
| Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) |
| if ( Min_CubesAreEqual( pCube, pThis ) ) |
| { |
| Min_CubeRecycle( p, pCube ); |
| break; |
| } |
| if ( pThis != NULL ) |
| continue; |
| pCube->pNext = p->ppStore[pCube->nLits]; |
| p->ppStore[pCube->nLits] = pCube; |
| p->nCubes++; |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns 1 if the given cube is contained in one of the cubes of the cover.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Min_CoverContainsCube( Min_Man_t * p, Min_Cube_t * pCube ) |
| { |
| Min_Cube_t * pThis; |
| int i; |
| /* |
| // this cube cannot be equal to any cube |
| Min_CoverForEachCube( p->ppStore[pCube->nLits], pThis ) |
| { |
| if ( Min_CubesAreEqual( pCube, pThis ) ) |
| { |
| Min_CubeWrite( stdout, pCube ); |
| assert( 0 ); |
| } |
| } |
| */ |
| // try to find a containing cube |
| for ( i = 0; i <= (int)pCube->nLits; i++ ) |
| Min_CoverForEachCube( p->ppStore[i], pThis ) |
| { |
| // skip the bubble |
| if ( pThis != p->pBubble && Min_CubeIsContained( pThis, pCube ) ) |
| return 1; |
| } |
| return 0; |
| } |
| |
| |
| ABC_NAMESPACE_HEADER_END |
| |
| #endif |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |