#include "mvc.h"
ABC_NAMESPACE_IMPL_START
static int bit_count[256] = {
0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
};
static void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew, int iColOld, int iColNew );
void Mvc_CoverSupport( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp )
{
Mvc_Cube_t * pCube;
Mvc_CubeBitClean( pSupp );
Mvc_CoverForEachCube( pCover, pCube )
Mvc_CubeBitOr( pSupp, pSupp, pCube );
}
void Mvc_CoverSupportAnd( Mvc_Cover_t * pCover, Mvc_Cube_t * pSupp )
{
Mvc_Cube_t * pCube;
Mvc_CubeBitFill( pSupp );
Mvc_CoverForEachCube( pCover, pCube )
Mvc_CubeBitAnd( pSupp, pSupp, pCube );
}
int Mvc_CoverSupportSizeBinary( Mvc_Cover_t * pCover )
{
Mvc_Cube_t * pSupp;
int Counter, i, v0, v1;
pSupp = Mvc_CubeAlloc( pCover );
Mvc_CoverSupportAnd( pCover, pSupp );
Counter = pCover->nBits/2;
for ( i = 0; i < pCover->nBits/2; i++ )
{
v0 = Mvc_CubeBitValue( pSupp, 2*i );
v1 = Mvc_CubeBitValue( pSupp, 2*i+1 );
if ( v0 && v1 )
Counter--;
}
Mvc_CubeFree( pCover, pSupp );
return Counter;
}
int Mvc_CoverSupportVarBelongs( Mvc_Cover_t * pCover, int iVar )
{
Mvc_Cube_t * pSupp;
int RetValue, v0, v1;
pSupp = Mvc_CubeAlloc( pCover );
Mvc_CoverSupportAnd( pCover, pSupp );
v0 = Mvc_CubeBitValue( pSupp, 2*iVar );
v1 = Mvc_CubeBitValue( pSupp, 2*iVar+1 );
RetValue = (int)( !v0 || !v1 );
Mvc_CubeFree( pCover, pSupp );
return RetValue;
}
void Mvc_CoverCommonCube( Mvc_Cover_t * pCover, Mvc_Cube_t * pComCube )
{
Mvc_Cube_t * pCube;
Mvc_CubeBitFill( pComCube );
Mvc_CoverForEachCube( pCover, pCube )
Mvc_CubeBitAnd( pComCube, pComCube, pCube );
}
int Mvc_CoverIsCubeFree( Mvc_Cover_t * pCover )
{
int Result;
Mvc_CoverAllocateMask( pCover );
Mvc_CoverCommonCube( pCover, pCover->pMask );
Mvc_CubeBitEmpty( Result, pCover->pMask );
return Result;
}
void Mvc_CoverMakeCubeFree( Mvc_Cover_t * pCover )
{
Mvc_Cube_t * pCube;
Mvc_CoverAllocateMask( pCover );
Mvc_CoverCommonCube( pCover, pCover->pMask );
Mvc_CoverForEachCube( pCover, pCube )
Mvc_CubeBitSharp( pCube, pCube, pCover->pMask );
}
Mvc_Cover_t * Mvc_CoverCommonCubeCover( Mvc_Cover_t * pCover )
{
Mvc_Cover_t * pRes;
Mvc_Cube_t * pCube;
pRes = Mvc_CoverClone( pCover );
pCube = Mvc_CubeAlloc( pRes );
Mvc_CoverCommonCube( pCover, pCube );
Mvc_CoverAddCubeTail( pRes, pCube );
return pRes;
}
int Mvc_CoverCheckSuppContainment( Mvc_Cover_t * pCover1, Mvc_Cover_t * pCover2 )
{
int Result;
assert( pCover1->nBits == pCover2->nBits );
Mvc_CoverAllocateMask( pCover1 );
Mvc_CoverSupport( pCover1, pCover1->pMask );
Mvc_CoverAllocateMask( pCover2 );
Mvc_CoverSupport( pCover2, pCover2->pMask );
Mvc_CubeBitNotImpl( Result, pCover2->pMask, pCover1->pMask );
return !Result;
}
int Mvc_CoverSetCubeSizes( Mvc_Cover_t * pCover )
{
Mvc_Cube_t * pCube;
unsigned char * pByte, * pByteStart, * pByteStop;
int nBytes, nOnes;
nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
Mvc_CoverForEachCube( pCover, pCube )
{
nOnes = 0;
pByteStart = (unsigned char *)pCube->pData;
pByteStop = pByteStart + nBytes;
for ( pByte = pByteStart; pByte < pByteStop; pByte++ )
nOnes += bit_count[*pByte];
Mvc_CubeSetSize( pCube, nOnes );
}
return 1;
}
int Mvc_CoverGetCubeSize( Mvc_Cube_t * pCube )
{
unsigned char * pByte, * pByteStart, * pByteStop;
int nOnes, nBytes, nBits;
nBits = (pCube->iLast + 1) * sizeof(Mvc_CubeWord_t) * 8 - pCube->nUnused;
nBytes = nBits / (8 * sizeof(unsigned char)) + (int)(nBits % (8 * sizeof(unsigned char)) > 0);
nOnes = 0;
pByteStart = (unsigned char *)pCube->pData;
pByteStop = pByteStart + nBytes;
for ( pByte = pByteStart; pByte < pByteStop; pByte++ )
nOnes += bit_count[*pByte];
return nOnes;
}
int Mvc_CoverCountCubePairDiffs( Mvc_Cover_t * pCover, unsigned char pDiffs[] )
{
Mvc_Cube_t * pCube1;
Mvc_Cube_t * pCube2;
Mvc_Cube_t * pMask;
unsigned char * pByte, * pByteStart, * pByteStop;
int nBytes, nOnes;
int nCubePairs;
pMask = Mvc_CubeAlloc( pCover );
nBytes = pCover->nBits / (8 * sizeof(unsigned char)) + (int)(pCover->nBits % (8 * sizeof(unsigned char)) > 0);
nCubePairs = 0;
Mvc_CoverForEachCube( pCover, pCube1 )
{
Mvc_CoverForEachCubeStart( Mvc_CubeReadNext(pCube1), pCube2 )
{
Mvc_CubeBitExor( pMask, pCube1, pCube2 );
pByteStart = (unsigned char *)pMask->pData;
pByteStop = pByteStart + nBytes;
nOnes = 0;
for ( pByte = pByteStart; pByte < pByteStop; pByte++ )
nOnes += bit_count[*pByte];
pDiffs[nCubePairs++] = nOnes;
}
}
Mvc_CubeFree( pCover, pMask );
return 1;
}
Mvc_Cover_t * Mvc_CoverRemap( Mvc_Cover_t * p, int * pVarsRem, int nVarsRem )
{
Mvc_Cover_t * pCover;
Mvc_Cube_t * pCube, * pCubeCopy;
int i;
pCover = Mvc_CoverAlloc( p->pMem, nVarsRem );
Mvc_CoverForEachCube( p, pCube )
{
pCubeCopy = Mvc_CubeAlloc( pCover );
Mvc_CubeBitFill( pCubeCopy ); Mvc_CoverAddCubeTail( pCover, pCubeCopy );
}
for ( i = 0; i < nVarsRem; i++ )
{
if (pVarsRem[i] < 0)
continue; assert( pVarsRem[i] >= 0 && pVarsRem[i] < p->nBits );
Mvc_CoverCopyColumn( p, pCover, pVarsRem[i], i );
}
return pCover;
}
void Mvc_CoverCopyColumn( Mvc_Cover_t * pCoverOld, Mvc_Cover_t * pCoverNew,
int iColOld, int iColNew )
{
Mvc_Cube_t * pCubeOld, * pCubeNew;
int iWordOld, iWordNew, iBitOld, iBitNew;
assert( Mvc_CoverReadCubeNum(pCoverOld) == Mvc_CoverReadCubeNum(pCoverNew) );
iWordOld = Mvc_CubeWhichWord(iColOld);
iBitOld = Mvc_CubeWhichBit(iColOld);
iWordNew = Mvc_CubeWhichWord(iColNew);
iBitNew = Mvc_CubeWhichBit(iColNew);
pCubeNew = Mvc_CoverReadCubeHead(pCoverNew);
Mvc_CoverForEachCube( pCoverOld, pCubeOld )
{
if ( pCubeOld->pData[iWordOld] & (1<<iBitOld) )
pCubeNew->pData[iWordNew] |= (1<<iBitNew);
else
pCubeNew->pData[iWordNew] &= ~(1<<iBitNew); pCubeNew = Mvc_CubeReadNext( pCubeNew );
}
}
void Mvc_CoverInverse( Mvc_Cover_t * pCover )
{
Mvc_Cube_t * pCube;
Mvc_CoverForEachCube( pCover, pCube )
Mvc_CubeBitNot( pCube );
}
Mvc_Cover_t * Mvc_CoverRemoveDontCareLits( Mvc_Cover_t * pCover )
{
Mvc_Cover_t * pCoverNew;
Mvc_Cube_t * pCube;
pCoverNew = Mvc_CoverDup( pCover );
Mvc_CoverForEachCube( pCoverNew, pCube )
Mvc_CubeBitRemoveDcs( pCube );
return pCoverNew;
}
Mvc_Cover_t * Mvc_CoverCofactor( Mvc_Cover_t * p, int iValue, int iValueOther )
{
Mvc_Cover_t * pCover;
Mvc_Cube_t * pCube, * pCubeCopy;
pCover = Mvc_CoverClone( p );
Mvc_CoverForEachCube( p, pCube )
if ( Mvc_CubeBitValue( pCube, iValue ) )
{
pCubeCopy = Mvc_CubeDup( pCover, pCube );
Mvc_CoverAddCubeTail( pCover, pCubeCopy );
Mvc_CubeBitInsert( pCubeCopy, iValueOther );
}
return pCover;
}
Mvc_Cover_t * Mvc_CoverFlipVar( Mvc_Cover_t * p, int iValue0, int iValue1 )
{
Mvc_Cover_t * pCover;
Mvc_Cube_t * pCube, * pCubeCopy;
int Value0, Value1, Temp;
assert( iValue0 + 1 == iValue1 );
pCover = Mvc_CoverClone( p );
Mvc_CoverForEachCube( p, pCube )
{
pCubeCopy = Mvc_CubeDup( pCover, pCube );
Mvc_CoverAddCubeTail( pCover, pCubeCopy );
Value0 = Mvc_CubeBitValue( pCubeCopy, iValue0 );
Value1 = Mvc_CubeBitValue( pCubeCopy, iValue1 );
if ( Value0 && Value1 )
continue;
assert( Value0 || Value1 );
Temp = Value0;
Value0 = Value1;
Value1 = Temp;
if ( Value0 )
Mvc_CubeBitInsert( pCubeCopy, iValue0 );
else
Mvc_CubeBitRemove( pCubeCopy, iValue0 );
if ( Value1 )
Mvc_CubeBitInsert( pCubeCopy, iValue1 );
else
Mvc_CubeBitRemove( pCubeCopy, iValue1 );
}
return pCover;
}
Mvc_Cover_t * Mvc_CoverUnivQuantify( Mvc_Cover_t * p,
int iValueA0, int iValueA1, int iValueB0, int iValueB1 )
{
Mvc_Cover_t * pCover;
Mvc_Cube_t * pCube, * pCubeCopy;
int ValueA0, ValueA1, ValueB0, ValueB1;
pCover = Mvc_CoverClone( p );
Mvc_CoverForEachCube( p, pCube )
{
ValueA0 = Mvc_CubeBitValue( pCube, iValueA0 );
ValueA1 = Mvc_CubeBitValue( pCube, iValueA1 );
ValueB0 = Mvc_CubeBitValue( pCube, iValueB0 );
ValueB1 = Mvc_CubeBitValue( pCube, iValueB1 );
assert( ValueA0 || ValueA1 );
assert( ValueB0 || ValueB1 );
if ( ValueA0 != ValueB0 && ValueA1 != ValueB1 )
continue;
pCubeCopy = Mvc_CubeDup( pCover, pCube );
Mvc_CoverAddCubeTail( pCover, pCubeCopy );
if ( ValueA0 && ValueB0 )
Mvc_CubeBitInsert( pCubeCopy, iValueA0 );
else
Mvc_CubeBitRemove( pCubeCopy, iValueA0 );
if ( ValueA1 && ValueB1 )
Mvc_CubeBitInsert( pCubeCopy, iValueA1 );
else
Mvc_CubeBitRemove( pCubeCopy, iValueA1 );
Mvc_CubeBitInsert( pCubeCopy, iValueB0 );
Mvc_CubeBitInsert( pCubeCopy, iValueB1 );
}
return pCover;
}
#if 0#endif
Mvc_Cover_t * Mvc_CoverTranspose( Mvc_Cover_t * pCover )
{
Mvc_Cover_t * pRes;
Mvc_Cube_t * pCubeRes, * pCube;
int nWord, nBit, i, iCube;
pRes = Mvc_CoverAlloc( pCover->pMem, Mvc_CoverReadCubeNum(pCover) );
for ( i = 0; i < pCover->nBits; i++ )
{
nWord = Mvc_CubeWhichWord(i);
nBit = Mvc_CubeWhichBit(i);
pCubeRes = Mvc_CubeAlloc( pRes );
Mvc_CubeBitClean( pCubeRes );
iCube = 0;
Mvc_CoverForEachCube( pCover, pCube )
{
if ( pCube->pData[nWord] & (1<<nBit) )
Mvc_CubeBitInsert( pCubeRes, iCube );
iCube++;
}
Mvc_CoverAddCubeTail( pRes, pCubeRes );
}
return pRes;
}
int Mvc_UtilsCheckUnusedZeros( Mvc_Cover_t * pCover )
{
unsigned Unsigned;
Mvc_Cube_t * pCube;
int nCubes;
nCubes = 0;
Mvc_CoverForEachCube( pCover, pCube )
{
if ( pCube->nUnused == 0 )
continue;
Unsigned = ( pCube->pData[pCube->iLast] &
(BITS_FULL << (32-pCube->nUnused)) );
if( Unsigned )
{
printf( "Cube %2d out of %2d contains dirty bits.\n", nCubes,
Mvc_CoverReadCubeNum(pCover) );
}
nCubes++;
}
return 1;
}
ABC_NAMESPACE_IMPL_END