| /**CFile**************************************************************** |
| |
| FileName [ifDec75.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [FPGA mapping based on priority cuts.] |
| |
| Synopsis [Performs additional check.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - November 21, 2006.] |
| |
| Revision [$Id: ifDec75.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "if.h" |
| #include "misc/extra/extra.h" |
| #include "bool/kit/kit.h" |
| #include "opt/dau/dau.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Finds all boundsets for which decomposition exists.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Dau_DsdCheckDecExist_rec( char * pStr, char ** p, int * pMatches, int * pnSupp ) |
| { |
| if ( **p == '!' ) |
| (*p)++; |
| while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') ) |
| (*p)++; |
| if ( **p >= 'a' && **p <= 'z' ) // var |
| { |
| (*pnSupp)++; |
| return 0; |
| } |
| if ( **p == '(' || **p == '[' ) // and/xor |
| { |
| unsigned Mask = 0; |
| int m, pSupps[8] = {0}, nParts = 0, nMints; |
| char * q = pStr + pMatches[ *p - pStr ]; |
| assert( *q == **p + 1 + (**p != '(') ); |
| for ( (*p)++; *p < q; (*p)++ ) |
| { |
| Mask |= Dau_DsdCheckDecExist_rec( pStr, p, pMatches, &pSupps[nParts] ); |
| *pnSupp += pSupps[nParts++]; |
| } |
| assert( *p == q ); |
| assert( nParts > 1 ); |
| nMints = (1 << nParts); |
| for ( m = 1; m < nMints; m++ ) |
| { |
| int i, Sum = 0; |
| for ( i = 0; i < nParts; i++ ) |
| if ( (m >> i) & 1 ) |
| Sum += pSupps[i]; |
| assert( Sum > 0 && Sum <= 8 ); |
| if ( Sum >= 2 ) |
| Mask |= (1 << Sum); |
| } |
| return Mask; |
| } |
| if ( **p == '<' || **p == '{' ) // mux |
| { |
| int uSupp; |
| unsigned Mask = 0; |
| char * q = pStr + pMatches[ *p - pStr ]; |
| assert( *q == **p + 1 + (**p != '(') ); |
| for ( (*p)++; *p < q; (*p)++ ) |
| { |
| uSupp = 0; |
| Mask |= Dau_DsdCheckDecExist_rec( pStr, p, pMatches, &uSupp ); |
| *pnSupp += uSupp; |
| } |
| assert( *p == q ); |
| Mask |= (1 << *pnSupp); |
| return Mask; |
| } |
| assert( 0 ); |
| return 0; |
| } |
| int Dau_DsdCheckDecExist( char * pDsd ) |
| { |
| int nSupp = 0; |
| if ( pDsd[1] == 0 ) |
| return 0; |
| return Dau_DsdCheckDecExist_rec( pDsd, &pDsd, Dau_DsdComputeMatches(pDsd), &nSupp ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Finds all boundsets for which AND-decomposition exists.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Dau_DsdCheckDecAndExist_rec( char * pStr, char ** p, int * pMatches, int * pnSupp ) |
| { |
| if ( **p == '!' ) |
| (*p)++; |
| while ( (**p >= 'A' && **p <= 'F') || (**p >= '0' && **p <= '9') ) |
| (*p)++; |
| if ( **p >= 'a' && **p <= 'z' ) // var |
| { |
| (*pnSupp)++; |
| return 0; |
| } |
| if ( **p == '(' ) // and |
| { |
| unsigned Mask = 0; |
| int m, i, pSupps[8] = {0}, nParts = 0, nSimple = 0, nMints; |
| char * q = pStr + pMatches[ *p - pStr ]; |
| assert( *q == **p + 1 + (**p != '(') ); |
| for ( (*p)++; *p < q; (*p)++ ) |
| { |
| Mask |= Dau_DsdCheckDecAndExist_rec( pStr, p, pMatches, &pSupps[nParts] ); |
| nSimple += (pSupps[nParts] == 1); |
| *pnSupp += pSupps[nParts++]; |
| } |
| assert( *p == q ); |
| assert( nParts > 1 ); |
| if ( nSimple > 0 ) |
| { |
| nMints = (1 << nParts); |
| for ( m = 1; m < nMints; m++ ) |
| { |
| int Sum = 0; |
| for ( i = 0; i < nParts; i++ ) |
| if ( pSupps[i] > 1 && ((m >> i) & 1) ) |
| Sum += pSupps[i]; |
| assert( Sum <= 8 ); |
| if ( Sum >= 2 ) |
| for ( i = 0; i < nSimple; i++ ) |
| Mask |= (1 << (Sum + i)); |
| } |
| for ( i = 2; i < nSimple; i++ ) |
| Mask |= (1 << i); |
| } |
| return Mask; |
| } |
| if ( **p == '<' || **p == '{' || **p == '[' ) // mux/xor/nondec |
| { |
| int uSupp; |
| unsigned Mask = 0; |
| char * q = pStr + pMatches[ *p - pStr ]; |
| assert( *q == **p + 1 + (**p != '(') ); |
| for ( (*p)++; *p < q; (*p)++ ) |
| { |
| uSupp = 0; |
| Mask |= Dau_DsdCheckDecAndExist_rec( pStr, p, pMatches, &uSupp ); |
| *pnSupp += uSupp; |
| } |
| assert( *p == q ); |
| return Mask; |
| } |
| assert( 0 ); |
| return 0; |
| } |
| int Dau_DsdCheckDecAndExist( char * pDsd ) |
| { |
| int nSupp = 0; |
| if ( pDsd[1] == 0 ) |
| return 1; |
| return Dau_DsdCheckDecAndExist_rec( pDsd, &pDsd, Dau_DsdComputeMatches(pDsd), &nSupp ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs additional check.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int If_CutPerformCheck75__( If_Man_t * p, unsigned * pTruth, int nVars, int nLeaves, char * pStr ) |
| { |
| char pDsdStr[1000]; |
| int nSizeNonDec, nDecExists, nDecAndExists; |
| static int Counter = 0; |
| Counter++; |
| if ( nLeaves < 6 ) |
| return 1; |
| assert( nLeaves <= 8 ); |
| if ( nLeaves < 8 && If_CutPerformCheck16( p, pTruth, nVars, nLeaves, "44" ) ) |
| return 1; |
| // check decomposability |
| nSizeNonDec = Dau_DsdDecompose( (word *)pTruth, nLeaves, 0, 0, pDsdStr ); |
| // printf( "Vars = %d %s", nLeaves, pDsdStr ); printf( "\n" ); |
| // Extra_PrintBinary( stdout, &nDecExists, 8 ); printf( "\n" ); |
| // Extra_PrintBinary( stdout, &nDecAndExists, 8 ); printf( "\n" ); |
| if ( nLeaves == 8 ) |
| { |
| if ( nSizeNonDec >= 5 ) |
| return 0; |
| nDecAndExists = Dau_DsdCheckDecAndExist( pDsdStr ); |
| if ( nDecAndExists & 0x10 ) // bit 4 |
| return 1; |
| else |
| return 0; |
| } |
| if ( nLeaves == 7 ) |
| { |
| extern void If_Dec7MinimumBase( word uTruth[2], int * pSupp, int nVarsAll, int * pnVars ); |
| word * pT = (word *)pTruth; |
| word pCof0[2], pCof1[2]; |
| int v, nVarsMin; |
| if ( nSizeNonDec < 5 ) |
| { |
| nDecExists = Dau_DsdCheckDecExist( pDsdStr ); |
| if ( nDecExists & 0x10 ) // bit 4 |
| return 1; |
| nDecAndExists = Dau_DsdCheckDecAndExist( pDsdStr ); |
| if ( nDecAndExists & 0x18 ) // bit 4, 3 |
| return 1; |
| } |
| // check cofactors |
| for ( v = 0; v < 7; v++ ) |
| { |
| pCof0[0] = pCof1[0] = pT[0]; |
| pCof0[1] = pCof1[1] = pT[1]; |
| Abc_TtCofactor0( pCof0, 2, v ); |
| Abc_TtCofactor1( pCof1, 2, v ); |
| if ( Abc_TtSupportSize(pCof0, 7) < 4 ) |
| { |
| If_Dec7MinimumBase( pCof1, NULL, 7, &nVarsMin ); |
| nSizeNonDec = Dau_DsdDecompose( pCof1, nVarsMin, 0, 0, pDsdStr ); |
| if ( nSizeNonDec >= 5 ) |
| continue; |
| nDecExists = Dau_DsdCheckDecExist( pDsdStr ); |
| if ( nDecExists & 0x18 ) // bit 4, 3 |
| return 1; |
| } |
| else if ( Abc_TtSupportSize(pCof1, 7) < 4 ) |
| { |
| If_Dec7MinimumBase( pCof0, NULL, 7, &nVarsMin ); |
| nSizeNonDec = Dau_DsdDecompose( pCof0, nVarsMin, 0, 0, pDsdStr ); |
| if ( nSizeNonDec >= 5 ) |
| continue; |
| nDecExists = Dau_DsdCheckDecExist( pDsdStr ); |
| if ( nDecExists & 0x18 ) // bit 4, 3 |
| return 1; |
| } |
| } |
| return 0; |
| } |
| if ( nLeaves == 6 ) |
| { |
| if ( nSizeNonDec < 5 ) |
| { |
| nDecExists = Dau_DsdCheckDecExist( pDsdStr ); |
| if ( nDecExists & 0x18 ) // bit 4, 3 |
| return 1; |
| nDecAndExists = Dau_DsdCheckDecAndExist( pDsdStr ); |
| if ( nDecAndExists & 0x1C ) // bit 4, 3, 2 |
| return 1; |
| } |
| return If_CutPerformCheck07( p, pTruth, nVars, nLeaves, pStr ); |
| } |
| assert( 0 ); |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs additional check.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int If_CutPerformCheck75( If_Man_t * p, unsigned * pTruth0, int nVars, int nLeaves, char * pStr ) |
| { |
| word * pTruthW = (word *)pTruth0; |
| word pTruth[4] = { pTruthW[0], pTruthW[1], pTruthW[2], pTruthW[3] }; |
| assert( nLeaves <= 8 ); |
| if ( !p->pPars->fCutMin ) |
| Abc_TtMinimumBase( pTruth, NULL, nLeaves, &nLeaves ); |
| if ( nLeaves < 6 ) |
| return 1; |
| // if ( nLeaves < 8 && If_CutPerformCheck07( p, (unsigned *)pTruth, nVars, nLeaves, "44" ) ) |
| if ( nLeaves < 8 && If_CutPerformCheck16( p, (unsigned *)pTruth, nVars, nLeaves, "44" ) ) |
| return 1; |
| // this is faster but not compatible with -z |
| if ( !p->pPars->fDeriveLuts && p->pPars->fEnableCheck75 && nLeaves == 8 ) |
| { |
| // char pDsdStr[1000] = "(!(abd)!(c!([fe][gh])))"; |
| char pDsdStr[1000]; |
| int nSizeNonDec = Dau_DsdDecompose( (word *)pTruth, nLeaves, 0, 0, pDsdStr ); |
| if ( nSizeNonDec >= 5 ) |
| return 0; |
| if ( Dau_DsdCheckDecAndExist(pDsdStr) & 0x10 ) // bit 4 |
| return 1; |
| return 0; |
| } |
| if ( If_CutPerformCheck45( p, (unsigned *)pTruth, nVars, nLeaves, pStr ) ) |
| return 1; |
| if ( If_CutPerformCheck54( p, (unsigned *)pTruth, nVars, nLeaves, pStr ) ) |
| return 1; |
| return 0; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |