diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2006-12-06 08:01:00 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2006-12-06 08:01:00 -0800 |
commit | 4cf99cae95c629b31d6d89c5dcea2eeb17654c85 (patch) | |
tree | dd5984cdf1b9332b800921fd89cf190aa2c4d8d9 /src/opt/kit/kitSop.c | |
parent | 38254947a57b9899909d8fbabfbf784690ed5a68 (diff) | |
download | abc-4cf99cae95c629b31d6d89c5dcea2eeb17654c85.tar.gz abc-4cf99cae95c629b31d6d89c5dcea2eeb17654c85.tar.bz2 abc-4cf99cae95c629b31d6d89c5dcea2eeb17654c85.zip |
Version abc61206
Diffstat (limited to 'src/opt/kit/kitSop.c')
-rw-r--r-- | src/opt/kit/kitSop.c | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/src/opt/kit/kitSop.c b/src/opt/kit/kitSop.c new file mode 100644 index 00000000..3fa81351 --- /dev/null +++ b/src/opt/kit/kitSop.c @@ -0,0 +1,570 @@ +/**CFile**************************************************************** + + FileName [kitSop.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Computation kit.] + + Synopsis [Procedures involving SOPs.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - Dec 6, 2006.] + + Revision [$Id: kitSop.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "kit.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Creates SOP from the cube array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopCreate( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nVars, Vec_Int_t * vMemory ) +{ + unsigned uCube; + int i; + // start the cover + cResult->nCubes = 0; + cResult->pCubes = Vec_IntFetch( vMemory, Vec_IntSize(vInput) ); + // add the cubes + Vec_IntForEachEntry( vInput, uCube, i ) + Kit_SopPushCube( cResult, uCube ); +} + +/**Function************************************************************* + + Synopsis [Creates SOP from the cube array.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopCreateInverse( Kit_Sop_t * cResult, Vec_Int_t * vInput, int nLits, Vec_Int_t * vMemory ) +{ + unsigned uCube, uMask = 0; + int i, nCubes = Vec_IntSize(vInput); + // start the cover + cResult->nCubes = 0; + cResult->pCubes = Vec_IntFetch( vMemory, nCubes ); + // add the cubes +// Vec_IntForEachEntry( vInput, uCube, i ) + for ( i = 0; i < nCubes; i++ ) + { + uCube = Vec_IntEntry( vInput, i ); + uMask = ((uCube | (uCube >> 1)) & 0x55555555); + uMask |= (uMask << 1); + Kit_SopPushCube( cResult, uCube ^ uMask ); + } +} + +/**Function************************************************************* + + Synopsis [Duplicates SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopDup( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory ) +{ + unsigned uCube; + int i; + // start the cover + cResult->nCubes = 0; + cResult->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) ); + // add the cubes + Kit_SopForEachCube( cSop, uCube, i ) + Kit_SopPushCube( cResult, uCube ); +} + +/**Function************************************************************* + + Synopsis [Derives the quotient of division by literal.] + + Description [Reduces the cover to be equal to the result of + division of the given cover by the literal.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopDivideByLiteralQuo( Kit_Sop_t * cSop, int iLit ) +{ + unsigned uCube; + int i, k = 0; + Kit_SopForEachCube( cSop, uCube, i ) + { + if ( Kit_CubeHasLit(uCube, iLit) ) + Kit_SopWriteCube( cSop, Kit_CubeRemLit(uCube, iLit), k++ ); + } + Kit_SopShrink( cSop, k ); +} + + +/**Function************************************************************* + + Synopsis [Divides cover by one cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopDivideByCube( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory ) +{ + unsigned uCube, uDiv; + int i; + // get the only cube + assert( Kit_SopCubeNum(cDiv) == 1 ); + uDiv = Kit_SopCube(cDiv, 0); + // allocate covers + vQuo->nCubes = 0; + vQuo->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) ); + vRem->nCubes = 0; + vRem->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) ); + // sort the cubes + Kit_SopForEachCube( cSop, uCube, i ) + { + if ( Kit_CubeContains( uCube, uDiv ) ) + Kit_SopPushCube( vQuo, Kit_CubeSharp(uCube, uDiv) ); + else + Kit_SopPushCube( vRem, uCube ); + } +} + +/**Function************************************************************* + + Synopsis [Divides cover by one cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopDivideInternal( Kit_Sop_t * cSop, Kit_Sop_t * cDiv, Kit_Sop_t * vQuo, Kit_Sop_t * vRem, Vec_Int_t * vMemory ) +{ + unsigned uCube, uDiv, uCube2, uDiv2, uQuo; + int i, i2, k, k2, nCubesRem; + assert( Kit_SopCubeNum(cSop) >= Kit_SopCubeNum(cDiv) ); + // consider special case + if ( Kit_SopCubeNum(cDiv) == 1 ) + { + Kit_SopDivideByCube( cSop, cDiv, vQuo, vRem, vMemory ); + return; + } + // allocate quotient + vQuo->nCubes = 0; + vQuo->pCubes = Vec_IntFetch( vMemory, Kit_SopCubeNum(cSop) / Kit_SopCubeNum(cDiv) ); + // for each cube of the cover + // it either belongs to the quotient or to the remainder + Kit_SopForEachCube( cSop, uCube, i ) + { + // skip taken cubes + if ( Kit_CubeIsMarked(uCube) ) + continue; + // find a matching cube in the divisor + Kit_SopForEachCube( cDiv, uDiv, k ) + if ( Kit_CubeContains( uCube, uDiv ) ) + break; + // the cube is not found + if ( k == Kit_SopCubeNum(cDiv) ) + continue; + // the quotient cube exists + uQuo = Kit_CubeSharp( uCube, uDiv ); + // find corresponding cubes for other cubes of the divisor + Kit_SopForEachCube( cDiv, uDiv2, k2 ) + { + if ( k2 == k ) + continue; + // find a matching cube + Kit_SopForEachCube( cSop, uCube2, i2 ) + { + // skip taken cubes + if ( Kit_CubeIsMarked(uCube2) ) + continue; + // check if the cube can be used + if ( Kit_CubeContains( uCube2, uDiv2 ) && uQuo == Kit_CubeSharp( uCube2, uDiv2 ) ) + break; + } + // the case when the cube is not found + if ( i2 == Kit_SopCubeNum(cSop) ) + break; + } + // we did not find some cubes - continue looking at other cubes + if ( k2 != Kit_SopCubeNum(cDiv) ) + continue; + // we found all cubes - add the quotient cube + Kit_SopPushCube( vQuo, uQuo ); + + // mark the first cube + Kit_SopWriteCube( cSop, Kit_CubeMark(uCube), i ); + // mark other cubes that have this quotient + Kit_SopForEachCube( cDiv, uDiv2, k2 ) + { + if ( k2 == k ) + continue; + // find a matching cube + Kit_SopForEachCube( cSop, uCube2, i2 ) + { + // skip taken cubes + if ( Kit_CubeIsMarked(uCube2) ) + continue; + // check if the cube can be used + if ( Kit_CubeContains( uCube2, uDiv2 ) && uQuo == Kit_CubeSharp( uCube2, uDiv2 ) ) + break; + } + assert( i2 < Kit_SopCubeNum(cSop) ); + // the cube is found, mark it + // (later we will add all unmarked cubes to the remainder) + Kit_SopWriteCube( cSop, Kit_CubeMark(uCube2), i2 ); + } + } + // determine the number of cubes in the remainder + nCubesRem = Kit_SopCubeNum(cSop) - Kit_SopCubeNum(vQuo) * Kit_SopCubeNum(cDiv); + // allocate remainder + vRem->nCubes = 0; + vRem->pCubes = Vec_IntFetch( vMemory, nCubesRem ); + // finally add the remaining unmarked cubes to the remainder + // and clean the marked cubes in the cover + Kit_SopForEachCube( cSop, uCube, i ) + { + if ( !Kit_CubeIsMarked(uCube) ) + { + Kit_SopPushCube( vRem, uCube ); + continue; + } + Kit_SopWriteCube( cSop, Kit_CubeUnmark(uCube), i ); + } + assert( nCubesRem == Kit_SopCubeNum(vRem) ); +} + +/**Function************************************************************* + + Synopsis [Returns the common cube.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline unsigned Kit_SopCommonCube( Kit_Sop_t * cSop ) +{ + unsigned uMask, uCube; + int i; + uMask = ~(unsigned)0; + Kit_SopForEachCube( cSop, uCube, i ) + uMask &= uCube; + return uMask; +} + +/**Function************************************************************* + + Synopsis [Makes the cover cube-free.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopMakeCubeFree( Kit_Sop_t * cSop ) +{ + unsigned uMask, uCube; + int i; + uMask = Kit_SopCommonCube( cSop ); + if ( uMask == 0 ) + return; + // remove the common cube + Kit_SopForEachCube( cSop, uCube, i ) + Kit_SopWriteCube( cSop, Kit_CubeSharp(uCube, uMask), i ); +} + +/**Function************************************************************* + + Synopsis [Checks if the cover is cube-free.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_SopIsCubeFree( Kit_Sop_t * cSop ) +{ + return Kit_SopCommonCube( cSop ) == 0; +} + +/**Function************************************************************* + + Synopsis [Creates SOP composes of the common cube of the given SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopCommonCubeCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, Vec_Int_t * vMemory ) +{ + assert( Kit_SopCubeNum(cSop) > 0 ); + cResult->nCubes = 0; + cResult->pCubes = Vec_IntFetch( vMemory, 1 ); + Kit_SopPushCube( cResult, Kit_SopCommonCube(cSop) ); +} + + +/**Function************************************************************* + + Synopsis [Find any literal that occurs more than once.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_SopAnyLiteral( Kit_Sop_t * cSop, int nLits ) +{ + unsigned uCube; + int i, k, nLitsCur; + // go through each literal + for ( i = 0; i < nLits; i++ ) + { + // go through all the cubes + nLitsCur = 0; + Kit_SopForEachCube( cSop, uCube, k ) + if ( Kit_CubeHasLit(uCube, i) ) + nLitsCur++; + if ( nLitsCur > 1 ) + return i; + } + return -1; +} + +/**Function************************************************************* + + Synopsis [Find the least often occurring literal.] + + Description [Find the least often occurring literal among those + that occur more than once.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_SopWorstLiteral( Kit_Sop_t * cSop, int nLits ) +{ + unsigned uCube; + int i, k, iMin, nLitsMin, nLitsCur; + int fUseFirst = 1; + + // go through each literal + iMin = -1; + nLitsMin = 1000000; + for ( i = 0; i < nLits; i++ ) + { + // go through all the cubes + nLitsCur = 0; + Kit_SopForEachCube( cSop, uCube, k ) + if ( Kit_CubeHasLit(uCube, i) ) + nLitsCur++; + // skip the literal that does not occur or occurs once + if ( nLitsCur < 2 ) + continue; + // check if this is the best literal + if ( fUseFirst ) + { + if ( nLitsMin > nLitsCur ) + { + nLitsMin = nLitsCur; + iMin = i; + } + } + else + { + if ( nLitsMin >= nLitsCur ) + { + nLitsMin = nLitsCur; + iMin = i; + } + } + } + if ( nLitsMin < 1000000 ) + return iMin; + return -1; +} + +/**Function************************************************************* + + Synopsis [Find the least often occurring literal.] + + Description [Find the least often occurring literal among those + that occur more than once.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_SopBestLiteral( Kit_Sop_t * cSop, int nLits, unsigned uMask ) +{ + unsigned uCube; + int i, k, iMax, nLitsMax, nLitsCur; + int fUseFirst = 1; + + // go through each literal + iMax = -1; + nLitsMax = -1; + for ( i = 0; i < nLits; i++ ) + { + if ( !Kit_CubeHasLit(uMask, i) ) + continue; + // go through all the cubes + nLitsCur = 0; + Kit_SopForEachCube( cSop, uCube, k ) + if ( Kit_CubeHasLit(uCube, i) ) + nLitsCur++; + // skip the literal that does not occur or occurs once + if ( nLitsCur < 2 ) + continue; + // check if this is the best literal + if ( fUseFirst ) + { + if ( nLitsMax < nLitsCur ) + { + nLitsMax = nLitsCur; + iMax = i; + } + } + else + { + if ( nLitsMax <= nLitsCur ) + { + nLitsMax = nLitsCur; + iMax = i; + } + } + } + if ( nLitsMax >= 0 ) + return iMax; + return -1; +} + +/**Function************************************************************* + + Synopsis [Computes a level-zero kernel.] + + Description [Modifies the cover to contain one level-zero kernel.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopDivisorZeroKernel_rec( Kit_Sop_t * cSop, int nLits ) +{ + int iLit; + // find any literal that occurs at least two times + iLit = Kit_SopWorstLiteral( cSop, nLits ); + if ( iLit == -1 ) + return; + // derive the cube-free quotient + Kit_SopDivideByLiteralQuo( cSop, iLit ); // the same cover + Kit_SopMakeCubeFree( cSop ); // the same cover + // call recursively + Kit_SopDivisorZeroKernel_rec( cSop, nLits ); // the same cover +} + +/**Function************************************************************* + + Synopsis [Computes the quick divisor of the cover.] + + Description [Returns 0, if there is no divisor other than trivial.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Kit_SopDivisor( Kit_Sop_t * cResult, Kit_Sop_t * cSop, int nLits, Vec_Int_t * vMemory ) +{ + if ( Kit_SopCubeNum(cSop) <= 1 ) + return 0; + if ( Kit_SopAnyLiteral( cSop, nLits ) == -1 ) + return 0; + // duplicate the cover + Kit_SopDup( cResult, cSop, vMemory ); + // perform the kerneling + Kit_SopDivisorZeroKernel_rec( cResult, nLits ); + assert( Kit_SopCubeNum(cResult) > 0 ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Create the one-literal cover with the best literal from cSop.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Kit_SopBestLiteralCover( Kit_Sop_t * cResult, Kit_Sop_t * cSop, unsigned uCube, int nLits, Vec_Int_t * vMemory ) +{ + int iLitBest; + // get the best literal + iLitBest = Kit_SopBestLiteral( cSop, nLits, uCube ); + // start the cover + cResult->nCubes = 0; + cResult->pCubes = Vec_IntFetch( vMemory, 1 ); + // set the cube + Kit_SopPushCube( cResult, Kit_CubeSetLit(0, iLitBest) ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |