/**CFile**************************************************************** FileName [lpkAbcMux.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Fast Boolean matching for LUT structures.] Synopsis [LUT-decomposition based on recursive MUX decomposition.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - April 28, 2007.] Revision [$Id: lpkAbcMux.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] ***********************************************************************/ #include "lpkInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Checks the possibility of MUX decomposition.] Description [Returns the best variable to use for MUX decomposition.] SideEffects [] SeeAlso [] ***********************************************************************/ Lpk_Res_t * Lpk_MuxAnalize( Lpk_Man_t * pMan, Lpk_Fun_t * p ) { static Lpk_Res_t Res, * pRes = &Res; int nSuppSize0, nSuppSize1, nSuppSizeS, nSuppSizeL; int Var, Area, Polarity, Delay, Delay0, Delay1, DelayA, DelayB; memset( pRes, 0, sizeof(Lpk_Res_t) ); assert( p->uSupp == Kit_BitMask(p->nVars) ); assert( p->fSupports ); // derive the delay and area after MUX-decomp with each var - and find the best var pRes->Variable = -1; Lpk_SuppForEachVar( p->uSupp, Var ) { nSuppSize0 = Kit_WordCountOnes(p->puSupps[2*Var+0]); nSuppSize1 = Kit_WordCountOnes(p->puSupps[2*Var+1]); assert( nSuppSize0 < (int)p->nVars ); assert( nSuppSize1 < (int)p->nVars ); if ( nSuppSize0 < 1 || nSuppSize1 < 1 ) continue; //printf( "%d %d ", nSuppSize0, nSuppSize1 ); if ( nSuppSize0 <= (int)p->nLutK - 2 && nSuppSize1 <= (int)p->nLutK - 2 ) { // include cof var into 0-block DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); Delay0 = Abc_MaxInt( DelayA, DelayB + 1 ); // include cof var into 1-block DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); Delay1 = Abc_MaxInt( DelayA, DelayB + 1 ); // get the best delay Delay = Abc_MinInt( Delay0, Delay1 ); Area = 2; Polarity = (int)(Delay == Delay1); } else if ( nSuppSize0 <= (int)p->nLutK - 2 ) { DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); Delay = Abc_MaxInt( DelayA, DelayB + 1 ); Area = 1 + Lpk_LutNumLuts( nSuppSize1, p->nLutK ); Polarity = 0; } else if ( nSuppSize1 <= (int)p->nLutK - 2 ) { DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); Delay = Abc_MaxInt( DelayA, DelayB + 1 ); Area = 1 + Lpk_LutNumLuts( nSuppSize0, p->nLutK ); Polarity = 1; } else if ( nSuppSize0 <= (int)p->nLutK ) { DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); Delay = Abc_MaxInt( DelayA, DelayB + 1 ); Area = 1 + Lpk_LutNumLuts( nSuppSize1+2, p->nLutK ); Polarity = 1; } else if ( nSuppSize1 <= (int)p->nLutK ) { DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); Delay = Abc_MaxInt( DelayA, DelayB + 1 ); Area = 1 + Lpk_LutNumLuts( nSuppSize0+2, p->nLutK ); Polarity = 0; } else { // include cof var into 0-block DelayA = Lpk_SuppDelay( p->puSupps[2*Var+0] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+1] , p->pDelays ); Delay0 = Abc_MaxInt( DelayA, DelayB + 1 ); // include cof var into 1-block DelayA = Lpk_SuppDelay( p->puSupps[2*Var+1] | (1<pDelays ); DelayB = Lpk_SuppDelay( p->puSupps[2*Var+0] , p->pDelays ); Delay1 = Abc_MaxInt( DelayA, DelayB + 1 ); // get the best delay Delay = Abc_MinInt( Delay0, Delay1 ); if ( Delay == Delay0 ) Area = Lpk_LutNumLuts( nSuppSize0+2, p->nLutK ) + Lpk_LutNumLuts( nSuppSize1, p->nLutK ); else Area = Lpk_LutNumLuts( nSuppSize1+2, p->nLutK ) + Lpk_LutNumLuts( nSuppSize0, p->nLutK ); Polarity = (int)(Delay == Delay1); } // find the best variable if ( Delay > (int)p->nDelayLim ) continue; if ( Area > (int)p->nAreaLim ) continue; nSuppSizeS = Abc_MinInt( nSuppSize0 + 2 *!Polarity, nSuppSize1 + 2 * Polarity ); nSuppSizeL = Abc_MaxInt( nSuppSize0 + 2 *!Polarity, nSuppSize1 + 2 * Polarity ); if ( nSuppSizeL > (int)p->nVars ) continue; if ( pRes->Variable == -1 || pRes->AreaEst > Area || (pRes->AreaEst == Area && pRes->nSuppSizeS + pRes->nSuppSizeL > nSuppSizeS + nSuppSizeL) || (pRes->AreaEst == Area && pRes->nSuppSizeS + pRes->nSuppSizeL == nSuppSizeS + nSuppSizeL && pRes->DelayEst > Delay) ) { pRes->Variable = Var; pRes->Polarity = Polarity; pRes->AreaEst = Area; pRes->DelayEst = Delay; pRes->nSuppSizeS = nSuppSizeS; pRes->nSuppSizeL = nSuppSizeL; } } return pRes->Variable == -1 ? NULL : pRes; } /**Function************************************************************* Synopsis [Transforms the function decomposed by the MUX decomposition.] Description [Returns the best variable to use for MUX decomposition.] SideEffects [] SeeAlso [] ***********************************************************************/ Lpk_Fun_t * Lpk_MuxSplit( Lpk_Man_t * pMan, Lpk_Fun_t * p, int Var, int Pol ) { Lpk_Fun_t * pNew; unsigned * pTruth = Lpk_FunTruth( p, 0 ); unsigned * pTruth0 = Lpk_FunTruth( p, 1 ); unsigned * pTruth1 = Lpk_FunTruth( p, 2 ); // unsigned uSupp; int iVarVac; assert( Var >= 0 && Var < (int)p->nVars ); assert( p->nAreaLim >= 2 ); assert( p->uSupp == Kit_BitMask(p->nVars) ); Kit_TruthCofactor0New( pTruth0, pTruth, p->nVars, Var ); Kit_TruthCofactor1New( pTruth1, pTruth, p->nVars, Var ); /* uSupp = Kit_TruthSupport( pTruth, p->nVars ); Extra_PrintBinary( stdout, &uSupp, 16 ); printf( "\n" ); uSupp = Kit_TruthSupport( pTruth0, p->nVars ); Extra_PrintBinary( stdout, &uSupp, 16 ); printf( "\n" ); uSupp = Kit_TruthSupport( pTruth1, p->nVars ); Extra_PrintBinary( stdout, &uSupp, 16 ); printf( "\n\n" ); */ // derive the new component pNew = Lpk_FunDup( p, Pol ? pTruth0 : pTruth1 ); // update the support of the old component p->uSupp = Kit_TruthSupport( Pol ? pTruth1 : pTruth0, p->nVars ); p->uSupp |= (1 << Var); // update the truth table of the old component iVarVac = Kit_WordFindFirstBit( ~p->uSupp ); assert( iVarVac < (int)p->nVars ); p->uSupp |= (1 << iVarVac); Kit_TruthIthVar( pTruth, p->nVars, iVarVac ); if ( Pol ) Kit_TruthMuxVar( pTruth, pTruth, pTruth1, p->nVars, Var ); else Kit_TruthMuxVar( pTruth, pTruth0, pTruth, p->nVars, Var ); assert( p->uSupp == Kit_TruthSupport(pTruth, p->nVars) ); // set the decomposed variable p->pFanins[iVarVac] = pNew->Id; p->pDelays[iVarVac] = p->nDelayLim - 1; // support minimize both p->fSupports = 0; Lpk_FunSuppMinimize( p ); Lpk_FunSuppMinimize( pNew ); // update delay and area requirements pNew->nDelayLim = p->nDelayLim - 1; if ( pNew->nVars <= pNew->nLutK ) { pNew->nAreaLim = 1; p->nAreaLim = p->nAreaLim - 1; } else if ( p->nVars <= p->nLutK ) { pNew->nAreaLim = p->nAreaLim - 1; p->nAreaLim = 1; } else if ( p->nVars < pNew->nVars ) { pNew->nAreaLim = p->nAreaLim / 2 + p->nAreaLim % 2; p->nAreaLim = p->nAreaLim / 2 - p->nAreaLim % 2; } else // if ( pNew->nVars < p->nVars ) { pNew->nAreaLim = p->nAreaLim / 2 - p->nAreaLim % 2; p->nAreaLim = p->nAreaLim / 2 + p->nAreaLim % 2; } pNew->fMark = 1; return pNew; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END