/**CFile**************************************************************** FileName [lpkSets.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Fast Boolean matching for LUT structures.] Synopsis [] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - April 28, 2007.] Revision [$Id: lpkSets.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $] ***********************************************************************/ #include "lpkInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// typedef struct Lpk_Set_t_ Lpk_Set_t; struct Lpk_Set_t_ { char iVar; // the cofactoring variable char Over; // the overlap in supports char SRed; // the support reduction char Size; // the size of the boundset unsigned uSubset0; // the first subset (with removed) unsigned uSubset1; // the second subset (with removed) }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Recursively computes decomposable subsets.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned Lpk_ComputeSets_rec( Kit_DsdNtk_t * p, int iLit, Vec_Int_t * vSets ) { unsigned i, iLitFanin, uSupport, uSuppCur; Kit_DsdObj_t * pObj; // consider the case of simple gate pObj = Kit_DsdNtkObj( p, Abc_Lit2Var(iLit) ); if ( pObj == NULL ) return (1 << Abc_Lit2Var(iLit)); if ( pObj->Type == KIT_DSD_AND || pObj->Type == KIT_DSD_XOR ) { unsigned uSupps[16], Limit, s; uSupport = 0; Kit_DsdObjForEachFanin( p, pObj, iLitFanin, i ) { uSupps[i] = Lpk_ComputeSets_rec( p, iLitFanin, vSets ); uSupport |= uSupps[i]; } // create all subsets, except empty and full Limit = (1 << pObj->nFans) - 1; for ( s = 1; s < Limit; s++ ) { uSuppCur = 0; for ( i = 0; i < pObj->nFans; i++ ) if ( s & (1 << i) ) uSuppCur |= uSupps[i]; Vec_IntPush( vSets, uSuppCur ); } return uSupport; } assert( pObj->Type == KIT_DSD_PRIME ); // get the cumulative support of all fanins uSupport = 0; Kit_DsdObjForEachFanin( p, pObj, iLitFanin, i ) { uSuppCur = Lpk_ComputeSets_rec( p, iLitFanin, vSets ); uSupport |= uSuppCur; Vec_IntPush( vSets, uSuppCur ); } return uSupport; } /**Function************************************************************* Synopsis [Computes the set of subsets of decomposable variables.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned Lpk_ComputeSets( Kit_DsdNtk_t * p, Vec_Int_t * vSets ) { unsigned uSupport, Entry; int Number, i; assert( p->nVars <= 16 ); Vec_IntClear( vSets ); Vec_IntPush( vSets, 0 ); if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_CONST1 ) return 0; if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_VAR ) { uSupport = ( 1 << Abc_Lit2Var(Kit_DsdNtkRoot(p)->pFans[0]) ); Vec_IntPush( vSets, uSupport ); return uSupport; } uSupport = Lpk_ComputeSets_rec( p, p->Root, vSets ); assert( (uSupport & 0xFFFF0000) == 0 ); Vec_IntPush( vSets, uSupport ); // set the remaining variables Vec_IntForEachEntry( vSets, Number, i ) { Entry = Number; Vec_IntWriteEntry( vSets, i, Entry | ((uSupport & ~Entry) << 16) ); } return uSupport; } /**Function************************************************************* Synopsis [Prints the sets of subsets.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Lpk_PrintSetOne( int uSupport ) { unsigned k; for ( k = 0; k < 16; k++ ) if ( uSupport & (1<> 16) ); // get the support reduction nSuppRed = nSuppSize - 1 - nSuppOver; // only consider support-reducing subsets if ( nSuppRed <= 0 ) continue; // check if this support is already used if ( TravId[uSupp] < nTravId ) { Used[nUsed++] = uSupp; TravId[uSupp] = nTravId; SRed[uSupp] = nSuppRed; Over[uSupp] = nSuppOver; Parents[uSupp] = (k << 16) | i; } else if ( TravId[uSupp] == nTravId && SRed[uSupp] < nSuppRed ) { TravId[uSupp] = nTravId; SRed[uSupp] = nSuppRed; Over[uSupp] = nSuppOver; Parents[uSupp] = (k << 16) | i; } } // find the minimum overlap nMinOver = 1000; for ( s = 0; s < nUsed; s++ ) if ( nMinOver > Over[Used[s]] ) nMinOver = Over[Used[s]]; // collect the accumulated ones for ( s = 0; s < nUsed; s++ ) if ( Over[Used[s]] == nMinOver ) { // save the entry if ( *pSize == nSizeLimit ) return; pEntry = pStore + (*pSize)++; i = Parents[Used[s]] & 0xFFFF; k = Parents[Used[s]] >> 16; pEntry->uSubset0 = Vec_IntEntry(vSets0, i); pEntry->uSubset1 = Vec_IntEntry(vSets1, k); Entry = pEntry->uSubset0 | pEntry->uSubset1; // record the cofactoring variable pEntry->iVar = iCofVar; // set the bound set size pEntry->Size = Kit_WordCountOnes( Entry & 0xFFFF ); // get the number of overlapping vars pEntry->Over = Kit_WordCountOnes( Entry & (Entry >> 16) ); // get the support reduction pEntry->SRed = pEntry->Size - 1 - pEntry->Over; assert( pEntry->SRed > 0 ); } } /**Function************************************************************* Synopsis [Prints one set.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Lpk_MapSuppPrintSet( Lpk_Set_t * pSet, int i ) { unsigned Entry; Entry = pSet->uSubset0 | pSet->uSubset1; printf( "%2d : ", i ); printf( "Var = %c ", 'a' + pSet->iVar ); printf( "Size = %2d ", pSet->Size ); printf( "Over = %2d ", pSet->Over ); printf( "SRed = %2d ", pSet->SRed ); Lpk_PrintSetOne( Entry ); printf( " " ); Lpk_PrintSetOne( Entry >> 16 ); printf( "\n" ); } /**Function************************************************************* Synopsis [Evaluates the cofactors.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ unsigned Lpk_MapSuppRedDecSelect( Lpk_Man_t * p, unsigned * pTruth, int nVars, int * piVar, int * piVarReused ) { static int nStoreSize = 256; static Lpk_Set_t pStore[256], * pSet, * pSetBest; Kit_DsdNtk_t * ppNtks[2], * pTemp; Vec_Int_t * vSets0 = p->vSets[0]; Vec_Int_t * vSets1 = p->vSets[1]; unsigned * pCof0 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 0 ); unsigned * pCof1 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 1 ); int nSets, i, SizeMax;//, SRedMax; unsigned Entry; int fVerbose = p->pPars->fVeryVerbose; // int fVerbose = 0; // collect decomposable subsets for each pair of cofactors if ( fVerbose ) { printf( "\nExploring support-reducing bound-sets of function:\n" ); Kit_DsdPrintFromTruth( pTruth, nVars ); } nSets = 0; for ( i = 0; i < nVars; i++ ) { if ( fVerbose ) printf( "Evaluating variable %c:\n", 'a'+i ); // evaluate the cofactor pair Kit_TruthCofactor0New( pCof0, pTruth, nVars, i ); Kit_TruthCofactor1New( pCof1, pTruth, nVars, i ); // decompose and expand ppNtks[0] = Kit_DsdDecompose( pCof0, nVars ); ppNtks[1] = Kit_DsdDecompose( pCof1, nVars ); ppNtks[0] = Kit_DsdExpand( pTemp = ppNtks[0] ); Kit_DsdNtkFree( pTemp ); ppNtks[1] = Kit_DsdExpand( pTemp = ppNtks[1] ); Kit_DsdNtkFree( pTemp ); if ( fVerbose ) Kit_DsdPrint( stdout, ppNtks[0] ); if ( fVerbose ) Kit_DsdPrint( stdout, ppNtks[1] ); // compute subsets Lpk_ComputeSets( ppNtks[0], vSets0 ); Lpk_ComputeSets( ppNtks[1], vSets1 ); // print subsets if ( fVerbose ) Lpk_PrintSets( vSets0 ); if ( fVerbose ) Lpk_PrintSets( vSets1 ); // free the networks Kit_DsdNtkFree( ppNtks[0] ); Kit_DsdNtkFree( ppNtks[1] ); // evaluate the pair Lpk_ComposeSets( vSets0, vSets1, nVars, i, pStore, &nSets, nStoreSize ); } // print the results if ( fVerbose ) printf( "\n" ); if ( fVerbose ) for ( i = 0; i < nSets; i++ ) Lpk_MapSuppPrintSet( pStore + i, i ); // choose the best subset SizeMax = 0; pSetBest = NULL; for ( i = 0; i < nSets; i++ ) { pSet = pStore + i; if ( pSet->Size > p->pPars->nLutSize - 1 ) continue; if ( SizeMax < pSet->Size ) { pSetBest = pSet; SizeMax = pSet->Size; } } /* // if the best is not choosen, select the one with largest reduction SRedMax = 0; if ( pSetBest == NULL ) { for ( i = 0; i < nSets; i++ ) { pSet = pStore + i; if ( SRedMax < pSet->SRed ) { pSetBest = pSet; SRedMax = pSet->SRed; } } } */ if ( pSetBest == NULL ) { if ( fVerbose ) printf( "Could not select a subset.\n" ); return 0; } else { if ( fVerbose ) printf( "Selected the following subset:\n" ); if ( fVerbose ) Lpk_MapSuppPrintSet( pSetBest, pSetBest - pStore ); } // prepare the return result // get the remaining variables Entry = ((pSetBest->uSubset0 >> 16) | (pSetBest->uSubset1 >> 16)); // get the variables to be removed Entry = Kit_BitMask(nVars) & ~(1<iVar) & ~Entry; // make sure there are some - otherwise it is not supp-red assert( Entry ); // remember the first such variable *piVarReused = Kit_WordFindFirstBit( Entry ); *piVar = pSetBest->iVar; return (pSetBest->uSubset1 << 16) | (pSetBest->uSubset0 & 0xFFFF); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END