| /**CFile**************************************************************** |
| |
| FileName [kitIsop.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Computation kit.] |
| |
| Synopsis [ISOP computation based on Morreale's algorithm.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - Dec 6, 2006.] |
| |
| Revision [$Id: kitIsop.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "kit.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| // ISOP computation fails if intermediate memory usage exceed this limit |
| #define KIT_ISOP_MEM_LIMIT (1<<20) |
| |
| // static procedures to compute ISOP |
| static unsigned * Kit_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore ); |
| static unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore ); |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computes ISOP from TT.] |
| |
| Description [Returns the cover in vMemory. Uses the rest of array in vMemory |
| as an intermediate memory storage. Returns the cover with -1 cubes, if the |
| the computation exceeded the memory limit (KIT_ISOP_MEM_LIMIT words of |
| intermediate data).] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth ) |
| { |
| Kit_Sop_t cRes, * pcRes = &cRes; |
| Kit_Sop_t cRes2, * pcRes2 = &cRes2; |
| unsigned * pResult; |
| int RetValue = 0; |
| assert( nVars >= 0 && nVars <= 16 ); |
| // if nVars < 5, make sure it does not depend on those vars |
| // for ( i = nVars; i < 5; i++ ) |
| // assert( !Kit_TruthVarInSupport(puTruth, 5, i) ); |
| // prepare memory manager |
| Vec_IntClear( vMemory ); |
| Vec_IntGrow( vMemory, KIT_ISOP_MEM_LIMIT ); |
| // compute ISOP for the direct polarity |
| pResult = Kit_TruthIsop_rec( puTruth, puTruth, nVars, pcRes, vMemory ); |
| if ( pcRes->nCubes == -1 ) |
| { |
| vMemory->nSize = -1; |
| return -1; |
| } |
| assert( Kit_TruthIsEqual( puTruth, pResult, nVars ) ); |
| if ( pcRes->nCubes == 0 || (pcRes->nCubes == 1 && pcRes->pCubes[0] == 0) ) |
| { |
| vMemory->pArray[0] = 0; |
| Vec_IntShrink( vMemory, pcRes->nCubes ); |
| return 0; |
| } |
| if ( fTryBoth ) |
| { |
| // compute ISOP for the complemented polarity |
| Kit_TruthNot( puTruth, puTruth, nVars ); |
| pResult = Kit_TruthIsop_rec( puTruth, puTruth, nVars, pcRes2, vMemory ); |
| if ( pcRes2->nCubes >= 0 ) |
| { |
| assert( Kit_TruthIsEqual( puTruth, pResult, nVars ) ); |
| if ( pcRes->nCubes > pcRes2->nCubes || (pcRes->nCubes == pcRes2->nCubes && pcRes->nLits > pcRes2->nLits) ) |
| { |
| RetValue = 1; |
| pcRes = pcRes2; |
| } |
| } |
| Kit_TruthNot( puTruth, puTruth, nVars ); |
| } |
| // printf( "%d ", vMemory->nSize ); |
| // move the cover representation to the beginning of the memory buffer |
| memmove( vMemory->pArray, pcRes->pCubes, pcRes->nCubes * sizeof(unsigned) ); |
| Vec_IntShrink( vMemory, pcRes->nCubes ); |
| return RetValue; |
| } |
| void Kit_TruthIsopPrintCover( Vec_Int_t * vCover, int nVars, int fCompl ) |
| { |
| int i, k, Entry, Literal; |
| if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover, 0) == 0) ) |
| { |
| printf( "Constant %d\n", Vec_IntSize(vCover) ); |
| return; |
| } |
| Vec_IntForEachEntry( vCover, Entry, i ) |
| { |
| for ( k = 0; k < nVars; k++ ) |
| { |
| Literal = 3 & (Entry >> (k << 1)); |
| if ( Literal == 1 ) // neg literal |
| printf( "0" ); |
| else if ( Literal == 2 ) // pos literal |
| printf( "1" ); |
| else if ( Literal == 0 ) |
| printf( "-" ); |
| else assert( 0 ); |
| } |
| printf( " %d\n", !fCompl ); |
| } |
| } |
| void Kit_TruthIsopPrint( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBoth ) |
| { |
| int fCompl = Kit_TruthIsop( puTruth, nVars, vCover, fTryBoth ); |
| Kit_TruthIsopPrintCover( vCover, nVars, fCompl ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computes ISOP 6 variables or more.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| unsigned * Kit_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore ) |
| { |
| Kit_Sop_t cRes0, cRes1, cRes2; |
| Kit_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2; |
| unsigned * puRes0, * puRes1, * puRes2; |
| unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp, * pTemp0, * pTemp1; |
| int i, k, Var, nWords, nWordsAll; |
| // assert( Kit_TruthIsImply( puOn, puOnDc, nVars ) ); |
| // allocate room for the resulting truth table |
| nWordsAll = Kit_TruthWordNum( nVars ); |
| pTemp = Vec_IntFetch( vStore, nWordsAll ); |
| if ( pTemp == NULL ) |
| { |
| pcRes->nCubes = -1; |
| return NULL; |
| } |
| // check for constants |
| if ( Kit_TruthIsConst0( puOn, nVars ) ) |
| { |
| pcRes->nLits = 0; |
| pcRes->nCubes = 0; |
| pcRes->pCubes = NULL; |
| Kit_TruthClear( pTemp, nVars ); |
| return pTemp; |
| } |
| if ( Kit_TruthIsConst1( puOnDc, nVars ) ) |
| { |
| pcRes->nLits = 0; |
| pcRes->nCubes = 1; |
| pcRes->pCubes = Vec_IntFetch( vStore, 1 ); |
| if ( pcRes->pCubes == NULL ) |
| { |
| pcRes->nCubes = -1; |
| return NULL; |
| } |
| pcRes->pCubes[0] = 0; |
| Kit_TruthFill( pTemp, nVars ); |
| return pTemp; |
| } |
| assert( nVars > 0 ); |
| // find the topmost var |
| for ( Var = nVars-1; Var >= 0; Var-- ) |
| if ( Kit_TruthVarInSupport( puOn, nVars, Var ) || |
| Kit_TruthVarInSupport( puOnDc, nVars, Var ) ) |
| break; |
| assert( Var >= 0 ); |
| // consider a simple case when one-word computation can be used |
| if ( Var < 5 ) |
| { |
| unsigned uRes = Kit_TruthIsop5_rec( puOn[0], puOnDc[0], Var+1, pcRes, vStore ); |
| for ( i = 0; i < nWordsAll; i++ ) |
| pTemp[i] = uRes; |
| return pTemp; |
| } |
| assert( Var >= 5 ); |
| nWords = Kit_TruthWordNum( Var ); |
| // cofactor |
| puOn0 = puOn; puOn1 = puOn + nWords; |
| puOnDc0 = puOnDc; puOnDc1 = puOnDc + nWords; |
| pTemp0 = pTemp; pTemp1 = pTemp + nWords; |
| // solve for cofactors |
| Kit_TruthSharp( pTemp0, puOn0, puOnDc1, Var ); |
| puRes0 = Kit_TruthIsop_rec( pTemp0, puOnDc0, Var, pcRes0, vStore ); |
| if ( pcRes0->nCubes == -1 ) |
| { |
| pcRes->nCubes = -1; |
| return NULL; |
| } |
| Kit_TruthSharp( pTemp1, puOn1, puOnDc0, Var ); |
| puRes1 = Kit_TruthIsop_rec( pTemp1, puOnDc1, Var, pcRes1, vStore ); |
| if ( pcRes1->nCubes == -1 ) |
| { |
| pcRes->nCubes = -1; |
| return NULL; |
| } |
| Kit_TruthSharp( pTemp0, puOn0, puRes0, Var ); |
| Kit_TruthSharp( pTemp1, puOn1, puRes1, Var ); |
| Kit_TruthOr( pTemp0, pTemp0, pTemp1, Var ); |
| Kit_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var ); |
| puRes2 = Kit_TruthIsop_rec( pTemp0, pTemp1, Var, pcRes2, vStore ); |
| if ( pcRes2->nCubes == -1 ) |
| { |
| pcRes->nCubes = -1; |
| return NULL; |
| } |
| // create the resulting cover |
| pcRes->nLits = pcRes0->nLits + pcRes1->nLits + pcRes2->nLits + pcRes0->nCubes + pcRes1->nCubes; |
| pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes; |
| pcRes->pCubes = Vec_IntFetch( vStore, pcRes->nCubes ); |
| if ( pcRes->pCubes == NULL ) |
| { |
| pcRes->nCubes = -1; |
| return NULL; |
| } |
| k = 0; |
| for ( i = 0; i < pcRes0->nCubes; i++ ) |
| pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+0)); |
| for ( i = 0; i < pcRes1->nCubes; i++ ) |
| pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+1)); |
| for ( i = 0; i < pcRes2->nCubes; i++ ) |
| pcRes->pCubes[k++] = pcRes2->pCubes[i]; |
| assert( k == pcRes->nCubes ); |
| // create the resulting truth table |
| Kit_TruthOr( pTemp0, puRes0, puRes2, Var ); |
| Kit_TruthOr( pTemp1, puRes1, puRes2, Var ); |
| // copy the table if needed |
| nWords <<= 1; |
| for ( i = 1; i < nWordsAll/nWords; i++ ) |
| for ( k = 0; k < nWords; k++ ) |
| pTemp[i*nWords + k] = pTemp[k]; |
| // verify in the end |
| // assert( Kit_TruthIsImply( puOn, pTemp, nVars ) ); |
| // assert( Kit_TruthIsImply( pTemp, puOnDc, nVars ) ); |
| return pTemp; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Computes ISOP for 5 variables or less.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore ) |
| { |
| unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; |
| Kit_Sop_t cRes0, cRes1, cRes2; |
| Kit_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2; |
| unsigned uOn0, uOn1, uOnDc0, uOnDc1, uRes0, uRes1, uRes2; |
| int i, k, Var; |
| assert( nVars <= 5 ); |
| assert( (uOn & ~uOnDc) == 0 ); |
| if ( uOn == 0 ) |
| { |
| pcRes->nLits = 0; |
| pcRes->nCubes = 0; |
| pcRes->pCubes = NULL; |
| return 0; |
| } |
| if ( uOnDc == 0xFFFFFFFF ) |
| { |
| pcRes->nLits = 0; |
| pcRes->nCubes = 1; |
| pcRes->pCubes = Vec_IntFetch( vStore, 1 ); |
| if ( pcRes->pCubes == NULL ) |
| { |
| pcRes->nCubes = -1; |
| return 0; |
| } |
| pcRes->pCubes[0] = 0; |
| return 0xFFFFFFFF; |
| } |
| assert( nVars > 0 ); |
| // find the topmost var |
| for ( Var = nVars-1; Var >= 0; Var-- ) |
| if ( Kit_TruthVarInSupport( &uOn, 5, Var ) || |
| Kit_TruthVarInSupport( &uOnDc, 5, Var ) ) |
| break; |
| assert( Var >= 0 ); |
| // cofactor |
| uOn0 = uOn1 = uOn; |
| uOnDc0 = uOnDc1 = uOnDc; |
| Kit_TruthCofactor0( &uOn0, Var + 1, Var ); |
| Kit_TruthCofactor1( &uOn1, Var + 1, Var ); |
| Kit_TruthCofactor0( &uOnDc0, Var + 1, Var ); |
| Kit_TruthCofactor1( &uOnDc1, Var + 1, Var ); |
| // solve for cofactors |
| uRes0 = Kit_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var, pcRes0, vStore ); |
| if ( pcRes0->nCubes == -1 ) |
| { |
| pcRes->nCubes = -1; |
| return 0; |
| } |
| uRes1 = Kit_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var, pcRes1, vStore ); |
| if ( pcRes1->nCubes == -1 ) |
| { |
| pcRes->nCubes = -1; |
| return 0; |
| } |
| uRes2 = Kit_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var, pcRes2, vStore ); |
| if ( pcRes2->nCubes == -1 ) |
| { |
| pcRes->nCubes = -1; |
| return 0; |
| } |
| // create the resulting cover |
| pcRes->nLits = pcRes0->nLits + pcRes1->nLits + pcRes2->nLits + pcRes0->nCubes + pcRes1->nCubes; |
| pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes; |
| pcRes->pCubes = Vec_IntFetch( vStore, pcRes->nCubes ); |
| if ( pcRes->pCubes == NULL ) |
| { |
| pcRes->nCubes = -1; |
| return 0; |
| } |
| k = 0; |
| for ( i = 0; i < pcRes0->nCubes; i++ ) |
| pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+0)); |
| for ( i = 0; i < pcRes1->nCubes; i++ ) |
| pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+1)); |
| for ( i = 0; i < pcRes2->nCubes; i++ ) |
| pcRes->pCubes[k++] = pcRes2->pCubes[i]; |
| assert( k == pcRes->nCubes ); |
| // derive the final truth table |
| uRes2 |= (uRes0 & ~uMasks[Var]) | (uRes1 & uMasks[Var]); |
| // assert( (uOn & ~uRes2) == 0 ); |
| // assert( (uRes2 & ~uOnDc) == 0 ); |
| return uRes2; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |