/**CFile**************************************************************** FileName [mpmTruth.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Configurable technology mapper.] Synopsis [Truth table manipulation.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 1, 2013.] Revision [$Id: mpmTruth.c,v 1.00 2013/06/01 00:00:00 alanmi Exp $] ***********************************************************************/ #include "mpmInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //#define MPM_TRY_NEW //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Unifies variable order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Mpm_TruthStretch( word * pTruth, Mpm_Cut_t * pCut, Mpm_Cut_t * pCut0, int nLimit ) { int i, k; for ( i = (int)pCut->nLeaves - 1, k = (int)pCut0->nLeaves - 1; i >= 0 && k >= 0; i-- ) { if ( pCut0->pLeaves[k] < pCut->pLeaves[i] ) continue; assert( pCut0->pLeaves[k] == pCut->pLeaves[i] ); if ( k < i ) Abc_TtSwapVars( pTruth, nLimit, k, i ); k--; } } /**Function************************************************************* Synopsis [Performs truth table support minimization.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Mpm_CutTruthMinimize6( Mpm_Man_t * p, Mpm_Cut_t * pCut ) { unsigned uSupport; int i, k, nSuppSize; // compute the support of the cut's function word t = *Mpm_CutTruth( p, Abc_Lit2Var(pCut->iFunc) ); uSupport = Abc_Tt6SupportAndSize( t, Mpm_CutLeafNum(pCut), &nSuppSize ); if ( nSuppSize == Mpm_CutLeafNum(pCut) ) return 0; p->nSmallSupp += (int)(nSuppSize < 2); // update leaves and signature for ( i = k = 0; i < Mpm_CutLeafNum(pCut); i++ ) { if ( ((uSupport >> i) & 1) ) { if ( k < i ) { pCut->pLeaves[k] = pCut->pLeaves[i]; Abc_TtSwapVars( &t, p->nLutSize, k, i ); } k++; } } assert( k == nSuppSize ); pCut->nLeaves = nSuppSize; assert( nSuppSize == Abc_TtSupportSize(&t, 6) ); // save the result pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert(p->vTtMem, &t), Abc_LitIsCompl(pCut->iFunc) ); return 1; } static inline int Mpm_CutTruthMinimize7( Mpm_Man_t * p, Mpm_Cut_t * pCut ) { unsigned uSupport; int i, k, nSuppSize; // compute the support of the cut's function word * pTruth = Mpm_CutTruth( p, Abc_Lit2Var(pCut->iFunc) ); uSupport = Abc_TtSupportAndSize( pTruth, Mpm_CutLeafNum(pCut), &nSuppSize ); if ( nSuppSize == Mpm_CutLeafNum(pCut) ) return 0; p->nSmallSupp += (int)(nSuppSize < 2); // update leaves and signature Abc_TtCopy( p->Truth, pTruth, p->nTruWords, 0 ); for ( i = k = 0; i < Mpm_CutLeafNum(pCut); i++ ) { if ( ((uSupport >> i) & 1) ) { if ( k < i ) { pCut->pLeaves[k] = pCut->pLeaves[i]; Abc_TtSwapVars( p->Truth, p->nLutSize, k, i ); } k++; } } assert( k == nSuppSize ); assert( nSuppSize == Abc_TtSupportSize(p->Truth, Mpm_CutLeafNum(pCut)) ); pCut->nLeaves = nSuppSize; // save the result pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert(p->vTtMem, p->Truth), Abc_LitIsCompl(pCut->iFunc) ); return 1; } /**Function************************************************************* Synopsis [Performs truth table computation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Mpm_CutComputeTruth6( Mpm_Man_t * p, Mpm_Cut_t * pCut, Mpm_Cut_t * pCut0, Mpm_Cut_t * pCut1, Mpm_Cut_t * pCutC, int fCompl0, int fCompl1, int fComplC, int Type ) { word * pTruth0 = Mpm_CutTruth( p, Abc_Lit2Var(pCut0->iFunc) ); word * pTruth1 = Mpm_CutTruth( p, Abc_Lit2Var(pCut1->iFunc) ); word * pTruthC = NULL; word t0 = (fCompl0 ^ pCut0->fCompl ^ Abc_LitIsCompl(pCut0->iFunc)) ? ~*pTruth0 : *pTruth0; word t1 = (fCompl1 ^ pCut1->fCompl ^ Abc_LitIsCompl(pCut1->iFunc)) ? ~*pTruth1 : *pTruth1; word tC = 0, t = 0; Mpm_TruthStretch( &t0, pCut, pCut0, p->nLutSize ); Mpm_TruthStretch( &t1, pCut, pCut1, p->nLutSize ); if ( pCutC ) { pTruthC = Mpm_CutTruth( p, Abc_Lit2Var(pCutC->iFunc) ); tC = (fComplC ^ pCutC->fCompl ^ Abc_LitIsCompl(pCutC->iFunc)) ? ~*pTruthC : *pTruthC; Mpm_TruthStretch( &tC, pCut, pCutC, p->nLutSize ); } assert( p->nLutSize <= 6 ); if ( Type == 1 ) t = t0 & t1; else if ( Type == 2 ) t = t0 ^ t1; else if ( Type == 3 ) t = (tC & t1) | (~tC & t0); else assert( 0 ); // save the result if ( t & 1 ) { t = ~t; pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, &t ), 1 ); } else pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, &t ), 0 ); if ( p->pPars->fCutMin ) return Mpm_CutTruthMinimize6( p, pCut ); return 1; } static inline int Mpm_CutComputeTruth7( Mpm_Man_t * p, Mpm_Cut_t * pCut, Mpm_Cut_t * pCut0, Mpm_Cut_t * pCut1, Mpm_Cut_t * pCutC, int fCompl0, int fCompl1, int fComplC, int Type ) { word * pTruth0 = Mpm_CutTruth( p, Abc_Lit2Var(pCut0->iFunc) ); word * pTruth1 = Mpm_CutTruth( p, Abc_Lit2Var(pCut1->iFunc) ); word * pTruthC = NULL; Abc_TtCopy( p->Truth0, pTruth0, p->nTruWords, fCompl0 ^ pCut0->fCompl ^ Abc_LitIsCompl(pCut0->iFunc) ); Abc_TtCopy( p->Truth1, pTruth1, p->nTruWords, fCompl1 ^ pCut1->fCompl ^ Abc_LitIsCompl(pCut1->iFunc) ); Mpm_TruthStretch( p->Truth0, pCut, pCut0, p->nLutSize ); Mpm_TruthStretch( p->Truth1, pCut, pCut1, p->nLutSize ); if ( pCutC ) { pTruthC = Mpm_CutTruth( p, Abc_Lit2Var(pCutC->iFunc) ); Abc_TtCopy( p->TruthC, pTruthC, p->nTruWords, fComplC ^ pCutC->fCompl ^ Abc_LitIsCompl(pCutC->iFunc) ); Mpm_TruthStretch( p->TruthC, pCut, pCutC, p->nLutSize ); } if ( Type == 1 ) Abc_TtAnd( p->Truth, p->Truth0, p->Truth1, p->nTruWords, 0 ); else if ( Type == 2 ) Abc_TtXor( p->Truth, p->Truth0, p->Truth1, p->nTruWords, 0 ); else if ( Type == 3 ) Abc_TtMux( p->Truth, p->TruthC, p->Truth1, p->Truth0, p->nTruWords ); else assert( 0 ); // save the result if ( p->Truth[0] & 1 ) { Abc_TtNot( p->Truth, p->nTruWords ); pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, p->Truth ), 1 ); } else pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, p->Truth ), 0 ); if ( p->pPars->fCutMin ) return Mpm_CutTruthMinimize7( p, pCut ); return 1; } int Mpm_CutComputeTruth( Mpm_Man_t * p, Mpm_Cut_t * pCut, Mpm_Cut_t * pCut0, Mpm_Cut_t * pCut1, Mpm_Cut_t * pCutC, int fCompl0, int fCompl1, int fComplC, int Type ) { int RetValue; if ( p->nLutSize <= 6 ) RetValue = Mpm_CutComputeTruth6( p, pCut, pCut0, pCut1, pCutC, fCompl0, fCompl1, fComplC, Type ); else RetValue = Mpm_CutComputeTruth7( p, pCut, pCut0, pCut1, pCutC, fCompl0, fCompl1, fComplC, Type ); #ifdef MPM_TRY_NEW { extern unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm ); char pCanonPerm[16]; memcpy( p->Truth0, p->Truth, sizeof(word) * p->nTruWords ); Abc_TtCanonicize( p->Truth0, pCut->nLimit, pCanonPerm ); } #endif return RetValue; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END