summaryrefslogtreecommitdiffstats
path: root/src/opt/lpk/lpkAbcDsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/opt/lpk/lpkAbcDsd.c')
-rw-r--r--src/opt/lpk/lpkAbcDsd.c395
1 files changed, 395 insertions, 0 deletions
diff --git a/src/opt/lpk/lpkAbcDsd.c b/src/opt/lpk/lpkAbcDsd.c
new file mode 100644
index 00000000..893844e0
--- /dev/null
+++ b/src/opt/lpk/lpkAbcDsd.c
@@ -0,0 +1,395 @@
+/**CFile****************************************************************
+
+ FileName [lpkAbcDsd.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: lpkAbcDsd.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "lpkInt.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Returns the variable whose cofs have min sum of supp sizes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Lpk_FunComputeMinSuppSizeVar( Lpk_Fun_t * p, unsigned ** ppTruths, int nTruths, unsigned ** ppCofs )
+{
+ int i, Var, VarBest, nSuppSize0, nSuppSize1, nSuppTotalMin, nSuppTotalCur, nSuppMaxMin, nSuppMaxCur;
+ VarBest = -1;
+ Lpk_SuppForEachVar( p->uSupp, Var )
+ {
+ nSuppMaxCur = 0;
+ nSuppTotalCur = 0;
+ for ( i = 0; i < nTruths; i++ )
+ {
+ Kit_TruthCofactor0New( ppCofs[2*i+0], ppTruths[i], p->nVars, Var );
+ Kit_TruthCofactor1New( ppCofs[2*i+1], ppTruths[i], p->nVars, Var );
+ nSuppSize0 = Kit_TruthSupportSize( ppCofs[2*i+0], p->nVars );
+ nSuppSize1 = Kit_TruthSupportSize( ppCofs[2*i+1], p->nVars );
+ nSuppMaxCur = ABC_MAX( nSuppMaxCur, nSuppSize0 );
+ nSuppMaxCur = ABC_MAX( nSuppMaxCur, nSuppSize1 );
+ nSuppTotalCur += nSuppSize0 + nSuppSize1;
+ }
+ if ( VarBest == -1 || nSuppTotalMin > nSuppTotalCur ||
+ (nSuppTotalMin == nSuppTotalCur && nSuppMaxMin > nSuppMaxCur) )
+ {
+ VarBest = Var;
+ nSuppMaxMin = nSuppMaxCur;
+ nSuppTotalMin = nSuppTotalCur;
+ }
+ }
+ // recompute cofactors for the best var
+ for ( i = 0; i < nTruths; i++ )
+ {
+ Kit_TruthCofactor0New( ppCofs[2*i+0], ppTruths[i], p->nVars, VarBest );
+ Kit_TruthCofactor1New( ppCofs[2*i+1], ppTruths[i], p->nVars, VarBest );
+ }
+ return VarBest;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Recursively computes decomposable subsets.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned Lpk_ComputeBoundSets_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, Kit_DsdLit2Var(iLit) );
+ if ( pObj == NULL )
+ return (1 << Kit_DsdLit2Var(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_ComputeBoundSets_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_ComputeBoundSets_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 []
+
+***********************************************************************/
+Vec_Int_t * Lpk_ComputeBoundSets( Kit_DsdNtk_t * p, int nSizeMax )
+{
+ Vec_Int_t * vSets;
+ unsigned uSupport, Entry;
+ int Number, i;
+ assert( p->nVars <= 16 );
+ vSets = Vec_IntAlloc( 100 );
+ Vec_IntPush( vSets, 0 );
+ if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_CONST1 )
+ return vSets;
+ if ( Kit_DsdNtkRoot(p)->Type == KIT_DSD_VAR )
+ {
+ uSupport = ( 1 << Kit_DsdLit2Var(Kit_DsdNtkRoot(p)->pFans[0]) );
+ Vec_IntPush( vSets, uSupport );
+ return vSets;
+ }
+ uSupport = Lpk_ComputeBoundSets_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 vSets;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Merges two bound sets.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Int_t * Lpk_MergeBoundSets( Vec_Int_t * vSets0, Vec_Int_t * vSets1 )
+{
+ Vec_Int_t * vSets;
+ int Entry0, Entry1, Entry;
+ int i, k;
+ vSets = Vec_IntAlloc( 100 );
+ Vec_IntForEachEntry( vSets0, Entry0, i )
+ Vec_IntForEachEntry( vSets1, Entry1, k )
+ {
+ Entry = Entry0 | Entry1;
+ if ( (Entry & (Entry >> 16)) )
+ continue;
+ Vec_IntPush( vSets, Entry );
+ }
+ return vSets;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates truth tables for cofactors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Lpk_FunAllocTruthTables( Lpk_Fun_t * p, int nCofDepth, unsigned * ppTruths[5][16] )
+{
+ int i;
+ assert( nCofDepth <= 4 );
+ ppTruths[0][0] = Lpk_FunTruth( p, 0 );
+ if ( nCofDepth >= 1 )
+ {
+ ppTruths[1][0] = Lpk_FunTruth( p, 1 );
+ ppTruths[1][1] = Lpk_FunTruth( p, 2 );
+ }
+ if ( nCofDepth >= 2 )
+ {
+ ppTruths[2][0] = ALLOC( unsigned, Kit_TruthWordNum(p->nVars) * 4 );
+ for ( i = 1; i < 4; i++ )
+ ppTruths[2][i] = ppTruths[2][0] + Kit_TruthWordNum(p->nVars) * i;
+ }
+ if ( nCofDepth >= 3 )
+ {
+ ppTruths[3][0] = ALLOC( unsigned, Kit_TruthWordNum(p->nVars) * 8 );
+ for ( i = 1; i < 8; i++ )
+ ppTruths[3][i] = ppTruths[3][0] + Kit_TruthWordNum(p->nVars) * i;
+ }
+ if ( nCofDepth >= 4 )
+ {
+ ppTruths[4][0] = ALLOC( unsigned, Kit_TruthWordNum(p->nVars) * 16 );
+ for ( i = 1; i < 16; i++ )
+ ppTruths[4][i] = ppTruths[4][0] + Kit_TruthWordNum(p->nVars) * i;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocates truth tables for cofactors.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Lpk_FunFreeTruthTables( Lpk_Fun_t * p, int nCofDepth, unsigned * ppTruths[5][16] )
+{
+ if ( nCofDepth >= 2 )
+ free( ppTruths[2][0] );
+ if ( nCofDepth >= 3 )
+ free( ppTruths[3][0] );
+ if ( nCofDepth >= 4 )
+ free( ppTruths[4][0] );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Performs DSD-based decomposition of the function.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Lpk_Res_t * Lpk_FunAnalizeDsd( Lpk_Fun_t * p, int nCofDepth )
+{
+ static Lpk_Res_t Res, * pRes = &Res;
+ unsigned * ppTruths[5][16];
+ Vec_Int_t * pvBSets[4][8];
+ Kit_DsdNtk_t * pNtkDec, * pTemp;
+ unsigned uBoundSet;
+ int i, k, nVarsBS, nVarsRem, Delay, Area;
+ Lpk_FunAllocTruthTables( p, nCofDepth, ppTruths );
+ // find the best cofactors
+ memset( pRes, 0, sizeof(Lpk_Res_t) );
+ pRes->nCofVars = nCofDepth;
+ for ( i = 0; i < nCofDepth; i++ )
+ pRes->pCofVars[i] = Lpk_FunComputeMinSuppSizeVar( p, ppTruths[i], 1<<i, ppTruths[i+1] );
+ // derive decomposed networks
+ for ( i = 0; i < (1<<nCofDepth); i++ )
+ {
+ pNtkDec = Kit_DsdDecompose( ppTruths[nCofDepth][i], p->nVars );
+ pNtkDec = Kit_DsdExpand( pTemp = pNtkDec ); Kit_DsdNtkFree( pTemp );
+ pvBSets[nCofDepth][i] = Lpk_ComputeBoundSets( pNtkDec, p->nLutK - nCofDepth );
+ Kit_DsdNtkFree( pNtkDec );
+ }
+ // derive the set of feasible boundsets
+ for ( i = nCofDepth - 1; i >= 0; i-- )
+ for ( k = 0; k < (1<<i); k++ )
+ pvBSets[i][k] = Lpk_MergeBoundSets( pvBSets[i+1][2*k+0], pvBSets[i+1][2*k+1] );
+ // compare the resulting boundsets
+ Vec_IntForEachEntry( pvBSets[0][0], uBoundSet, i )
+ {
+ if ( uBoundSet == 0 )
+ continue;
+ assert( (uBoundSet & (uBoundSet >> 16)) == 0 );
+ nVarsBS = Kit_WordCountOnes( uBoundSet & 0xFFFF );
+ nVarsRem = p->nVars - nVarsBS + nCofDepth + 1;
+ Delay = 1 + Lpk_SuppDelay( uBoundSet & 0xFFFF, p->pDelays );
+ Area = 1 + Lpk_LutNumLuts( nVarsRem, p->nLutK );
+ if ( Delay > (int)p->nDelayLim || Area > (int)p->nAreaLim )
+ continue;
+ if ( uBoundSet == 0 || pRes->DelayEst > Delay || pRes->DelayEst == Delay && pRes->nSuppSizeL > nVarsRem )
+ {
+ pRes->nBSVars = nVarsBS;
+ pRes->BSVars = uBoundSet;
+ pRes->nSuppSizeS = nVarsBS;
+ pRes->nSuppSizeL = nVarsRem;
+ pRes->DelayEst = Delay;
+ pRes->AreaEst = Area;
+ }
+ }
+ // free cofactor storage
+ Lpk_FunFreeTruthTables( p, nCofDepth, ppTruths );
+ return pRes;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Splits the function into two subfunctions using DSD.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Lpk_Fun_t * Lpk_FunSplitDsd( Lpk_Fun_t * p, char * pCofVars, int nCofVars, unsigned uBoundSet )
+{
+ Kit_DsdMan_t * pDsdMan;
+ Kit_DsdNtk_t * pNtkDec, * pTemp;
+ unsigned * pTruth = Lpk_FunTruth( p, 0 );
+ unsigned * pTruth0 = Lpk_FunTruth( p, 1 );
+ unsigned * pTruth1 = Lpk_FunTruth( p, 2 );
+ Lpk_Fun_t * pNew;
+ unsigned * ppTruths[5][16];
+ char pBSVars[5];
+ int i, k, nVars, nCofs;
+ // get the bound set variables
+ nVars = Lpk_SuppToVars( uBoundSet, pBSVars );
+ // compute the cofactors
+ Lpk_FunAllocTruthTables( p, nCofVars, ppTruths );
+ for ( i = 0; i < nCofVars; i++ )
+ for ( k = 0; k < (1<<i); k++ )
+ {
+ Kit_TruthCofactor0New( ppTruths[i+1][2*k+0], ppTruths[i][k], p->nVars, pCofVars[i] );
+ Kit_TruthCofactor1New( ppTruths[i+1][2*k+1], ppTruths[i][k], p->nVars, pCofVars[i] );
+ }
+ // decompose each cofactor w.r.t. the bound set
+ nCofs = (1<<nCofVars);
+ pDsdMan = Kit_DsdManAlloc( p->nVars, p->nVars * 4 );
+ for ( k = 0; k < nCofs; k++ )
+ {
+ pNtkDec = Kit_DsdDecompose( ppTruths[nCofVars][k], p->nVars );
+ pNtkDec = Kit_DsdExpand( pTemp = pNtkDec ); Kit_DsdNtkFree( pTemp );
+ Kit_DsdTruthPartialTwo( pDsdMan, pNtkDec, uBoundSet, pBSVars[0], ppTruths[nCofVars+1][k], ppTruths[nCofVars+1][nCofs+k] );
+ Kit_DsdNtkFree( pNtkDec );
+ }
+ Kit_DsdManFree( pDsdMan );
+ // compute the composition function
+ for ( i = nCofVars - 1; i >= 1; i-- )
+ for ( k = 0; k < (1<<i); k++ )
+ Kit_TruthMuxVar( ppTruths[i][k], ppTruths[i+1][2*k+0], ppTruths[i+1][2*k+1], nVars, pCofVars[i] );
+ // now the composition/decomposition functions are in pTruth0/pTruth1
+
+ // derive the new component
+ pNew = Lpk_FunDup( p, pTruth1 );
+ // update the old component
+ Kit_TruthCopy( pTruth, pTruth0, p->nVars );
+ p->uSupp = Kit_TruthSupport( pTruth0, p->nVars );
+ p->pFanins[pBSVars[0]] = pNew->Id;
+ p->pDelays[pBSVars[0]] = Lpk_SuppDelay( pNew->uSupp, pNew->pDelays );
+ // support minimize both
+ Lpk_FunSuppMinimize( p );
+ Lpk_FunSuppMinimize( pNew );
+ // update delay and area requirements
+ pNew->nDelayLim = p->nDelayLim - 1;
+ pNew->nAreaLim = 1;
+ p->nAreaLim = p->nAreaLim - 1;
+
+ // free cofactor storage
+ Lpk_FunFreeTruthTables( p, nCofVars, ppTruths );
+ return pNew;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+