diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2012-01-21 04:30:10 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2012-01-21 04:30:10 -0800 |
commit | 8014f25f6db719fa62336f997963532a14c568f6 (patch) | |
tree | c691ee91a3a2d452a2bd24ac89a8c717beaa7af7 /src/bool/bdc | |
parent | c44cc5de9429e6b4f1c05045fcf43c9cb96437b5 (diff) | |
download | abc-8014f25f6db719fa62336f997963532a14c568f6.tar.gz abc-8014f25f6db719fa62336f997963532a14c568f6.tar.bz2 abc-8014f25f6db719fa62336f997963532a14c568f6.zip |
Major restructuring of the code.
Diffstat (limited to 'src/bool/bdc')
-rw-r--r-- | src/bool/bdc/bdc.h | 92 | ||||
-rw-r--r-- | src/bool/bdc/bdcCore.c | 314 | ||||
-rw-r--r-- | src/bool/bdc/bdcDec.c | 751 | ||||
-rw-r--r-- | src/bool/bdc/bdcInt.h | 165 | ||||
-rw-r--r-- | src/bool/bdc/bdcSpfd.c | 1176 | ||||
-rw-r--r-- | src/bool/bdc/bdcTable.c | 134 | ||||
-rw-r--r-- | src/bool/bdc/bdc_.c | 54 | ||||
-rw-r--r-- | src/bool/bdc/module.make | 5 |
8 files changed, 2691 insertions, 0 deletions
diff --git a/src/bool/bdc/bdc.h b/src/bool/bdc/bdc.h new file mode 100644 index 00000000..6c88857a --- /dev/null +++ b/src/bool/bdc/bdc.h @@ -0,0 +1,92 @@ +/**CFile**************************************************************** + + FileName [bdc.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Truth-table-based bi-decomposition engine.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 30, 2007.] + + Revision [$Id: bdc.h,v 1.00 2007/01/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__aig__bdc__bdc_h +#define ABC__aig__bdc__bdc_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Bdc_Fun_t_ Bdc_Fun_t; +typedef struct Bdc_Man_t_ Bdc_Man_t; +typedef struct Bdc_Par_t_ Bdc_Par_t; +struct Bdc_Par_t_ +{ + // general parameters + int nVarsMax; // the maximum support + int fVerbose; // enable basic stats + int fVeryVerbose; // enable detailed stats +}; + +// working with complemented attributes of objects +static inline int Bdc_IsComplement( Bdc_Fun_t * p ) { return (int)((ABC_PTRUINT_T)p & (ABC_PTRUINT_T)01); } +static inline Bdc_Fun_t * Bdc_Regular( Bdc_Fun_t * p ) { return (Bdc_Fun_t *)((ABC_PTRUINT_T)p & ~(ABC_PTRUINT_T)01); } +static inline Bdc_Fun_t * Bdc_Not( Bdc_Fun_t * p ) { return (Bdc_Fun_t *)((ABC_PTRUINT_T)p ^ (ABC_PTRUINT_T)01); } +static inline Bdc_Fun_t * Bdc_NotCond( Bdc_Fun_t * p, int c ) { return (Bdc_Fun_t *)((ABC_PTRUINT_T)p ^ (ABC_PTRUINT_T)(c!=0)); } + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== bdcCore.c ==========================================================*/ +extern Bdc_Man_t * Bdc_ManAlloc( Bdc_Par_t * pPars ); +extern void Bdc_ManFree( Bdc_Man_t * p ); +extern int Bdc_ManDecompose( Bdc_Man_t * p, unsigned * puFunc, unsigned * puCare, int nVars, Vec_Ptr_t * vDivs, int nNodesMax ); +extern Bdc_Fun_t * Bdc_ManFunc( Bdc_Man_t * p, int i ); +extern Bdc_Fun_t * Bdc_ManRoot( Bdc_Man_t * p ); +extern int Bdc_ManNodeNum( Bdc_Man_t * p ); +extern Bdc_Fun_t * Bdc_FuncFanin0( Bdc_Fun_t * p ); +extern Bdc_Fun_t * Bdc_FuncFanin1( Bdc_Fun_t * p ); +extern void * Bdc_FuncCopy( Bdc_Fun_t * p ); +extern int Bdc_FuncCopyInt( Bdc_Fun_t * p ); +extern void Bdc_FuncSetCopy( Bdc_Fun_t * p, void * pCopy ); +extern void Bdc_FuncSetCopyInt( Bdc_Fun_t * p, int iCopy ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/bool/bdc/bdcCore.c b/src/bool/bdc/bdcCore.c new file mode 100644 index 00000000..58324f81 --- /dev/null +++ b/src/bool/bdc/bdcCore.c @@ -0,0 +1,314 @@ +/**CFile**************************************************************** + + FileName [bdcCore.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Truth-table-based bi-decomposition engine.] + + Synopsis [The gateway to bi-decomposition.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 30, 2007.] + + Revision [$Id: bdcCore.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bdcInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Accessing contents of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bdc_Fun_t * Bdc_ManFunc( Bdc_Man_t * p, int i ) { return Bdc_FunWithId(p, i); } +Bdc_Fun_t * Bdc_ManRoot( Bdc_Man_t * p ) { return p->pRoot; } +int Bdc_ManNodeNum( Bdc_Man_t * p ) { return p->nNodes; } +Bdc_Fun_t * Bdc_FuncFanin0( Bdc_Fun_t * p ) { return p->pFan0; } +Bdc_Fun_t * Bdc_FuncFanin1( Bdc_Fun_t * p ) { return p->pFan1; } +void * Bdc_FuncCopy( Bdc_Fun_t * p ) { return p->pCopy; } +int Bdc_FuncCopyInt( Bdc_Fun_t * p ) { return p->iCopy; } +void Bdc_FuncSetCopy( Bdc_Fun_t * p, void * pCopy ) { p->pCopy = pCopy; } +void Bdc_FuncSetCopyInt( Bdc_Fun_t * p, int iCopy ) { p->iCopy = iCopy; } + +/**Function************************************************************* + + Synopsis [Allocate resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bdc_Man_t * Bdc_ManAlloc( Bdc_Par_t * pPars ) +{ + Bdc_Man_t * p; + p = ABC_ALLOC( Bdc_Man_t, 1 ); + memset( p, 0, sizeof(Bdc_Man_t) ); + assert( pPars->nVarsMax > 1 && pPars->nVarsMax < 16 ); + p->pPars = pPars; + p->nWords = Kit_TruthWordNum( pPars->nVarsMax ); + p->nDivsLimit = 200; + // internal nodes + p->nNodesAlloc = 512; + p->pNodes = ABC_ALLOC( Bdc_Fun_t, p->nNodesAlloc ); + // memory + p->vMemory = Vec_IntStart( 8 * p->nWords * p->nNodesAlloc ); + Vec_IntClear(p->vMemory); + // set up hash table + p->nTableSize = (1 << p->pPars->nVarsMax); + p->pTable = ABC_ALLOC( Bdc_Fun_t *, p->nTableSize ); + memset( p->pTable, 0, sizeof(Bdc_Fun_t *) * p->nTableSize ); + p->vSpots = Vec_IntAlloc( 256 ); + // truth tables + p->vTruths = Vec_PtrAllocTruthTables( p->pPars->nVarsMax ); + p->puTemp1 = ABC_ALLOC( unsigned, 4 * p->nWords ); + p->puTemp2 = p->puTemp1 + p->nWords; + p->puTemp3 = p->puTemp2 + p->nWords; + p->puTemp4 = p->puTemp3 + p->nWords; + // start the internal ISFs + p->pIsfOL = &p->IsfOL; Bdc_IsfStart( p, p->pIsfOL ); + p->pIsfOR = &p->IsfOR; Bdc_IsfStart( p, p->pIsfOR ); + p->pIsfAL = &p->IsfAL; Bdc_IsfStart( p, p->pIsfAL ); + p->pIsfAR = &p->IsfAR; Bdc_IsfStart( p, p->pIsfAR ); + return p; +} + +/**Function************************************************************* + + Synopsis [Deallocate resynthesis manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_ManFree( Bdc_Man_t * p ) +{ + if ( p->pPars->fVerbose ) + { + printf( "Bi-decomposition stats: Calls = %d. Nodes = %d. Reuse = %d.\n", + p->numCalls, p->numNodes, p->numReuse ); + printf( "ANDs = %d. ORs = %d. Weak = %d. Muxes = %d. Memory = %.2f K\n", + p->numAnds, p->numOrs, p->numWeaks, p->numMuxes, 4.0 * Vec_IntSize(p->vMemory) / (1<<10) ); + ABC_PRT( "Cache", p->timeCache ); + ABC_PRT( "Check", p->timeCheck ); + ABC_PRT( "Muxes", p->timeMuxes ); + ABC_PRT( "Supps", p->timeSupps ); + ABC_PRT( "TOTAL", p->timeTotal ); + } + Vec_IntFree( p->vMemory ); + Vec_IntFree( p->vSpots ); + Vec_PtrFree( p->vTruths ); + ABC_FREE( p->puTemp1 ); + ABC_FREE( p->pNodes ); + ABC_FREE( p->pTable ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Clears the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_ManPrepare( Bdc_Man_t * p, Vec_Ptr_t * vDivs ) +{ + unsigned * puTruth; + Bdc_Fun_t * pNode; + int i; + Bdc_TableClear( p ); + Vec_IntClear( p->vMemory ); + // add constant 1 and elementary vars + p->nNodes = 0; + p->nNodesNew = - 1 - p->nVars - (vDivs? Vec_PtrSize(vDivs) : 0); + // add constant 1 + pNode = Bdc_FunNew( p ); + pNode->Type = BDC_TYPE_CONST1; + pNode->puFunc = (unsigned *)Vec_IntFetch(p->vMemory, p->nWords); + Kit_TruthFill( pNode->puFunc, p->nVars ); + pNode->uSupp = 0; + Bdc_TableAdd( p, pNode ); + // add variables + for ( i = 0; i < p->nVars; i++ ) + { + pNode = Bdc_FunNew( p ); + pNode->Type = BDC_TYPE_PI; + pNode->puFunc = (unsigned *)Vec_PtrEntry( p->vTruths, i ); + pNode->uSupp = (1 << i); + Bdc_TableAdd( p, pNode ); + } + // add the divisors + if ( vDivs ) + Vec_PtrForEachEntry( unsigned *, vDivs, puTruth, i ) + { + pNode = Bdc_FunNew( p ); + pNode->Type = BDC_TYPE_PI; + pNode->puFunc = puTruth; + pNode->uSupp = Kit_TruthSupport( puTruth, p->nVars ); + Bdc_TableAdd( p, pNode ); + if ( i == p->nDivsLimit ) + break; + } + assert( p->nNodesNew == 0 ); +} + +/**Function************************************************************* + + Synopsis [Clears the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_ManDecPrint( Bdc_Man_t * p ) +{ + Bdc_Fun_t * pNode; + int i; + printf( " 0 : Const 1\n" ); + for ( i = 1; i < p->nNodes; i++ ) + { + printf( " %d : ", i ); + pNode = p->pNodes + i; + if ( pNode->Type == BDC_TYPE_PI ) + printf( "PI " ); + else + { + printf( "%s%d &", Bdc_IsComplement(pNode->pFan0)? "-":"", Bdc_FunId(p,Bdc_Regular(pNode->pFan0)) ); + printf( " %s%d ", Bdc_IsComplement(pNode->pFan1)? "-":"", Bdc_FunId(p,Bdc_Regular(pNode->pFan1)) ); + } + Extra_PrintBinary( stdout, pNode->puFunc, (1<<p->nVars) ); + printf( "\n" ); + } + printf( "Root = %s%d.\n", Bdc_IsComplement(p->pRoot)? "-":"", Bdc_FunId(p,Bdc_Regular(p->pRoot)) ); +} + +/**Function************************************************************* + + Synopsis [Performs decomposition of one function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_ManDecompose( Bdc_Man_t * p, unsigned * puFunc, unsigned * puCare, int nVars, Vec_Ptr_t * vDivs, int nNodesMax ) +{ + Bdc_Isf_t Isf, * pIsf = &Isf; + int clk = clock(); + assert( nVars <= p->pPars->nVarsMax ); + // set current manager parameters + p->nVars = nVars; + p->nWords = Kit_TruthWordNum( nVars ); + p->nNodesMax = nNodesMax; + Bdc_ManPrepare( p, vDivs ); + if ( puCare && Kit_TruthIsConst0( puCare, nVars ) ) + { + p->pRoot = Bdc_Not(p->pNodes); + return 0; + } + // copy the function + Bdc_IsfStart( p, pIsf ); + if ( puCare ) + { + Kit_TruthAnd( pIsf->puOn, puCare, puFunc, p->nVars ); + Kit_TruthSharp( pIsf->puOff, puCare, puFunc, p->nVars ); + } + else + { + Kit_TruthCopy( pIsf->puOn, puFunc, p->nVars ); + Kit_TruthNot( pIsf->puOff, puFunc, p->nVars ); + } + Bdc_SuppMinimize( p, pIsf ); + // call decomposition + p->pRoot = Bdc_ManDecompose_rec( p, pIsf ); + p->timeTotal += clock() - clk; + p->numCalls++; + p->numNodes += p->nNodesNew; + if ( p->pRoot == NULL ) + return -1; + if ( !Bdc_ManNodeVerify( p, pIsf, p->pRoot ) ) + printf( "Bdc_ManDecompose(): Internal verification failed.\n" ); +// assert( Bdc_ManNodeVerify( p, pIsf, p->pRoot ) ); + return p->nNodesNew; +} + +/**Function************************************************************* + + Synopsis [Performs decomposition of one function.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_ManDecomposeTest( unsigned uTruth, int nVars ) +{ + static int Counter = 0; + static int Total = 0; + Bdc_Par_t Pars = {0}, * pPars = &Pars; + Bdc_Man_t * p; + int RetValue; +// unsigned uCare = ~0x888f888f; + unsigned uCare = ~0; +// unsigned uFunc = 0x88888888; +// unsigned uFunc = 0xf888f888; +// unsigned uFunc = 0x117e117e; +// unsigned uFunc = 0x018b018b; + unsigned uFunc = uTruth; + + pPars->nVarsMax = 8; + p = Bdc_ManAlloc( pPars ); + RetValue = Bdc_ManDecompose( p, &uFunc, &uCare, nVars, NULL, 1000 ); + Total += RetValue; + printf( "%5d : Nodes = %5d. Total = %8d.\n", ++Counter, RetValue, Total ); +// Bdc_ManDecPrint( p ); + Bdc_ManFree( p ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/bool/bdc/bdcDec.c b/src/bool/bdc/bdcDec.c new file mode 100644 index 00000000..61f46f17 --- /dev/null +++ b/src/bool/bdc/bdcDec.c @@ -0,0 +1,751 @@ +/**CFile**************************************************************** + + FileName [bdcDec.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Truth-table-based bi-decomposition engine.] + + Synopsis [Decomposition procedures.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 30, 2007.] + + Revision [$Id: bdcDec.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bdcInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Minimizes the support of the ISF.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SuppMinimize2( Bdc_Man_t * p, Bdc_Isf_t * pIsf ) +{ + int v; + int clk = 0; // Suppress "might be used uninitialized" + if ( p->pPars->fVerbose ) + clk = clock(); + // compute support + pIsf->uSupp = Kit_TruthSupport( pIsf->puOn, p->nVars ) | + Kit_TruthSupport( pIsf->puOff, p->nVars ); + // go through the support variables + for ( v = 0; v < p->nVars; v++ ) + { + if ( (pIsf->uSupp & (1 << v)) == 0 ) + continue; + Kit_TruthExistNew( p->puTemp1, pIsf->puOn, p->nVars, v ); + Kit_TruthExistNew( p->puTemp2, pIsf->puOff, p->nVars, v ); + if ( !Kit_TruthIsDisjoint( p->puTemp1, p->puTemp2, p->nVars ) ) + continue; +// if ( !Kit_TruthVarIsVacuous( pIsf->puOn, pIsf->puOff, p->nVars, v ) ) +// continue; + // remove the variable + Kit_TruthCopy( pIsf->puOn, p->puTemp1, p->nVars ); + Kit_TruthCopy( pIsf->puOff, p->puTemp2, p->nVars ); +// Kit_TruthExist( pIsf->puOn, p->nVars, v ); +// Kit_TruthExist( pIsf->puOff, p->nVars, v ); + pIsf->uSupp &= ~(1 << v); + } + if ( p->pPars->fVerbose ) + p->timeSupps += clock() - clk; +} + +/**Function************************************************************* + + Synopsis [Minimizes the support of the ISF.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SuppMinimize( Bdc_Man_t * p, Bdc_Isf_t * pIsf ) +{ + int v; + int clk = 0; // Suppress "might be used uninitialized" + if ( p->pPars->fVerbose ) + clk = clock(); + // go through the support variables + pIsf->uSupp = 0; + for ( v = 0; v < p->nVars; v++ ) + { + if ( !Kit_TruthVarInSupport( pIsf->puOn, p->nVars, v ) && + !Kit_TruthVarInSupport( pIsf->puOff, p->nVars, v ) ) + continue; + if ( Kit_TruthVarIsVacuous( pIsf->puOn, pIsf->puOff, p->nVars, v ) ) + { + Kit_TruthExist( pIsf->puOn, p->nVars, v ); + Kit_TruthExist( pIsf->puOff, p->nVars, v ); + continue; + } + pIsf->uSupp |= (1 << v); + } + if ( p->pPars->fVerbose ) + p->timeSupps += clock() - clk; +} + +/**Function************************************************************* + + Synopsis [Updates the ISF of the right after the left was decompoosed.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_DecomposeUpdateRight( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Isf_t * pIsfL, Bdc_Isf_t * pIsfR, Bdc_Fun_t * pFunc0, Bdc_Type_t Type ) +{ + unsigned * puTruth = p->puTemp1; + // get the truth table of the left branch + if ( Bdc_IsComplement(pFunc0) ) + Kit_TruthNot( puTruth, Bdc_Regular(pFunc0)->puFunc, p->nVars ); + else + Kit_TruthCopy( puTruth, pFunc0->puFunc, p->nVars ); + // split into parts + if ( Type == BDC_TYPE_OR ) + { +// Right.Q = bdd_appex( Q, CompSpecLeftF, bddop_diff, setRightRes ); +// Right.R = bdd_exist( R, setRightRes ); + +// if ( pR->Q ) Cudd_RecursiveDeref( dd, pR->Q ); +// if ( pR->R ) Cudd_RecursiveDeref( dd, pR->R ); +// pR->Q = Cudd_bddAndAbstract( dd, pF->Q, Cudd_Not(CompSpecF), pL->V ); Cudd_Ref( pR->Q ); +// pR->R = Cudd_bddExistAbstract( dd, pF->R, pL->V ); Cudd_Ref( pR->R ); + +// assert( pR->R != b0 ); +// return (int)( pR->Q == b0 ); + + Kit_TruthSharp( pIsfR->puOn, pIsf->puOn, puTruth, p->nVars ); + Kit_TruthExistSet( pIsfR->puOn, pIsfR->puOn, p->nVars, pIsfL->uUniq ); + Kit_TruthExistSet( pIsfR->puOff, pIsf->puOff, p->nVars, pIsfL->uUniq ); +// assert( Kit_TruthIsDisjoint(pIsfR->puOn, pIsfR->puOff, p->nVars) ); + assert( !Kit_TruthIsConst0(pIsfR->puOff, p->nVars) ); + return Kit_TruthIsConst0(pIsfR->puOn, p->nVars); + } + else if ( Type == BDC_TYPE_AND ) + { +// Right.R = bdd_appex( R, CompSpecLeftF, bddop_and, setRightRes ); +// Right.Q = bdd_exist( Q, setRightRes ); + +// if ( pR->Q ) Cudd_RecursiveDeref( dd, pR->Q ); +// if ( pR->R ) Cudd_RecursiveDeref( dd, pR->R ); +// pR->R = Cudd_bddAndAbstract( dd, pF->R, CompSpecF, pL->V ); Cudd_Ref( pR->R ); +// pR->Q = Cudd_bddExistAbstract( dd, pF->Q, pL->V ); Cudd_Ref( pR->Q ); + +// assert( pR->Q != b0 ); +// return (int)( pR->R == b0 ); + + Kit_TruthAnd( pIsfR->puOff, pIsf->puOff, puTruth, p->nVars ); + Kit_TruthExistSet( pIsfR->puOff, pIsfR->puOff, p->nVars, pIsfL->uUniq ); + Kit_TruthExistSet( pIsfR->puOn, pIsf->puOn, p->nVars, pIsfL->uUniq ); +// assert( Kit_TruthIsDisjoint(pIsfR->puOn, pIsfR->puOff, p->nVars) ); + assert( !Kit_TruthIsConst0(pIsfR->puOn, p->nVars) ); + return Kit_TruthIsConst0(pIsfR->puOff, p->nVars); + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Checks existence of OR-bidecomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Bdc_DecomposeGetCost( Bdc_Man_t * p, int nLeftVars, int nRightVars ) +{ + assert( nLeftVars > 0 ); + assert( nRightVars > 0 ); + // compute the decomposition coefficient + if ( nLeftVars >= nRightVars ) + return BDC_SCALE * (p->nVars * nRightVars + nLeftVars); + else // if ( nLeftVars < nRightVars ) + return BDC_SCALE * (p->nVars * nLeftVars + nRightVars); +} + +/**Function************************************************************* + + Synopsis [Checks existence of weak OR-bidecomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_DecomposeFindInitialVarSet( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Isf_t * pIsfL, Bdc_Isf_t * pIsfR ) +{ + char pVars[16]; + int v, nVars, Beg, End; + + assert( pIsfL->uSupp == 0 ); + assert( pIsfR->uSupp == 0 ); + + // fill in the variables + nVars = 0; + for ( v = 0; v < p->nVars; v++ ) + if ( pIsf->uSupp & (1 << v) ) + pVars[nVars++] = v; + + // try variable pairs + for ( Beg = 0; Beg < nVars; Beg++ ) + { + Kit_TruthExistNew( p->puTemp1, pIsf->puOff, p->nVars, pVars[Beg] ); + for ( End = nVars - 1; End > Beg; End-- ) + { + Kit_TruthExistNew( p->puTemp2, pIsf->puOff, p->nVars, pVars[End] ); + if ( Kit_TruthIsDisjoint3(pIsf->puOn, p->puTemp1, p->puTemp2, p->nVars) ) + { + pIsfL->uUniq = (1 << pVars[Beg]); + pIsfR->uUniq = (1 << pVars[End]); + return 1; + } + } + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Checks existence of weak OR-bidecomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_DecomposeWeakOr( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Isf_t * pIsfL, Bdc_Isf_t * pIsfR ) +{ + int v, VarCost; + int VarBest = -1; // Suppress "might be used uninitialized" + int Cost, VarCostBest = 0; + + for ( v = 0; v < p->nVars; v++ ) + { + if ( (pIsf->uSupp & (1 << v)) == 0 ) + continue; +// if ( (Q & !bdd_exist( R, VarSetXa )) != bddfalse ) +// Exist = Cudd_bddExistAbstract( dd, pF->R, Var ); Cudd_Ref( Exist ); +// if ( Cudd_bddIteConstant( dd, pF->Q, Cudd_Not(Exist), b0 ) != b0 ) + + Kit_TruthExistNew( p->puTemp1, pIsf->puOff, p->nVars, v ); + if ( !Kit_TruthIsImply( pIsf->puOn, p->puTemp1, p->nVars ) ) + { + // measure the cost of this variable +// VarCost = bdd_satcountset( bdd_forall( Q, VarSetXa ), VarCube ); +// Univ = Cudd_bddUnivAbstract( dd, pF->Q, Var ); Cudd_Ref( Univ ); +// VarCost = Kit_TruthCountOnes( Univ, p->nVars ); +// Cudd_RecursiveDeref( dd, Univ ); + + Kit_TruthForallNew( p->puTemp2, pIsf->puOn, p->nVars, v ); + VarCost = Kit_TruthCountOnes( p->puTemp2, p->nVars ); + if ( VarCost == 0 ) + VarCost = 1; + if ( VarCostBest < VarCost ) + { + VarCostBest = VarCost; + VarBest = v; + } + } + } + + // derive the components for weak-bi-decomposition if the variable is found + if ( VarCostBest ) + { +// funQLeftRes = Q & bdd_exist( R, setRightORweak ); +// Temp = Cudd_bddExistAbstract( dd, pF->R, VarBest ); Cudd_Ref( Temp ); +// pL->Q = Cudd_bddAnd( dd, pF->Q, Temp ); Cudd_Ref( pL->Q ); +// Cudd_RecursiveDeref( dd, Temp ); + + Kit_TruthExistNew( p->puTemp1, pIsf->puOff, p->nVars, VarBest ); + Kit_TruthAnd( pIsfL->puOn, pIsf->puOn, p->puTemp1, p->nVars ); + +// pL->R = pF->R; Cudd_Ref( pL->R ); +// pL->V = VarBest; Cudd_Ref( pL->V ); + Kit_TruthCopy( pIsfL->puOff, pIsf->puOff, p->nVars ); + pIsfL->uUniq = (1 << VarBest); + pIsfR->uUniq = 0; + +// assert( pL->Q != b0 ); +// assert( pL->R != b0 ); +// assert( Cudd_bddIteConstant( dd, pL->Q, pL->R, b0 ) == b0 ); +// assert( Kit_TruthIsDisjoint(pIsfL->puOn, pIsfL->puOff, p->nVars) ); + + // express cost in percents of the covered boolean space + Cost = VarCostBest * BDC_SCALE / (1<<p->nVars); + if ( Cost == 0 ) + Cost = 1; + return Cost; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Checks existence of OR-bidecomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_DecomposeOr( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Isf_t * pIsfL, Bdc_Isf_t * pIsfR ) +{ + unsigned uSupportRem; + int v, nLeftVars = 1, nRightVars = 1; + // clean the var sets + Bdc_IsfStart( p, pIsfL ); + Bdc_IsfStart( p, pIsfR ); + // check that the support is correct + assert( Kit_TruthSupport(pIsf->puOn, p->nVars) == Kit_TruthSupport(pIsf->puOff, p->nVars) ); + assert( pIsf->uSupp == Kit_TruthSupport(pIsf->puOn, p->nVars) ); + // find initial variable sets + if ( !Bdc_DecomposeFindInitialVarSet( p, pIsf, pIsfL, pIsfR ) ) + return Bdc_DecomposeWeakOr( p, pIsf, pIsfL, pIsfR ); + // prequantify the variables in the offset + Kit_TruthExistSet( p->puTemp1, pIsf->puOff, p->nVars, pIsfL->uUniq ); + Kit_TruthExistSet( p->puTemp2, pIsf->puOff, p->nVars, pIsfR->uUniq ); + // go through the remaining variables + uSupportRem = pIsf->uSupp & ~pIsfL->uUniq & ~pIsfR->uUniq; + for ( v = 0; v < p->nVars; v++ ) + { + if ( (uSupportRem & (1 << v)) == 0 ) + continue; + // prequantify this variable + Kit_TruthExistNew( p->puTemp3, p->puTemp1, p->nVars, v ); + Kit_TruthExistNew( p->puTemp4, p->puTemp2, p->nVars, v ); + if ( nLeftVars < nRightVars ) + { +// if ( (Q & bdd_exist( pF->R, pL->V & VarNew ) & bdd_exist( pF->R, pR->V )) == bddfalse ) +// if ( VerifyORCondition( dd, pF->Q, pF->R, pL->V, pR->V, VarNew ) ) + if ( Kit_TruthIsDisjoint3(pIsf->puOn, p->puTemp3, p->puTemp2, p->nVars) ) + { +// pL->V &= VarNew; + pIsfL->uUniq |= (1 << v); + nLeftVars++; + Kit_TruthCopy( p->puTemp1, p->puTemp3, p->nVars ); + } +// else if ( (Q & bdd_exist( pF->R, pR->V & VarNew ) & bdd_exist( pF->R, pL->V )) == bddfalse ) + else if ( Kit_TruthIsDisjoint3(pIsf->puOn, p->puTemp4, p->puTemp1, p->nVars) ) + { +// pR->V &= VarNew; + pIsfR->uUniq |= (1 << v); + nRightVars++; + Kit_TruthCopy( p->puTemp2, p->puTemp4, p->nVars ); + } + } + else + { +// if ( (Q & bdd_exist( pF->R, pR->V & VarNew ) & bdd_exist( pF->R, pL->V )) == bddfalse ) + if ( Kit_TruthIsDisjoint3(pIsf->puOn, p->puTemp4, p->puTemp1, p->nVars) ) + { +// pR->V &= VarNew; + pIsfR->uUniq |= (1 << v); + nRightVars++; + Kit_TruthCopy( p->puTemp2, p->puTemp4, p->nVars ); + } +// else if ( (Q & bdd_exist( pF->R, pL->V & VarNew ) & bdd_exist( pF->R, pR->V )) == bddfalse ) + else if ( Kit_TruthIsDisjoint3(pIsf->puOn, p->puTemp3, p->puTemp2, p->nVars) ) + { +// pL->V &= VarNew; + pIsfL->uUniq |= (1 << v); + nLeftVars++; + Kit_TruthCopy( p->puTemp1, p->puTemp3, p->nVars ); + } + } + } + + // derive the functions Q and R for the left branch +// pL->Q = bdd_appex( pF->Q, bdd_exist( pF->R, pL->V ), bddop_and, pR->V ); +// pL->R = bdd_exist( pF->R, pR->V ); + +// Temp = Cudd_bddExistAbstract( dd, pF->R, pL->V ); Cudd_Ref( Temp ); +// pL->Q = Cudd_bddAndAbstract( dd, pF->Q, Temp, pR->V ); Cudd_Ref( pL->Q ); +// Cudd_RecursiveDeref( dd, Temp ); +// pL->R = Cudd_bddExistAbstract( dd, pF->R, pR->V ); Cudd_Ref( pL->R ); + + Kit_TruthAnd( pIsfL->puOn, pIsf->puOn, p->puTemp1, p->nVars ); + Kit_TruthExistSet( pIsfL->puOn, pIsfL->puOn, p->nVars, pIsfR->uUniq ); + Kit_TruthCopy( pIsfL->puOff, p->puTemp2, p->nVars ); + +// assert( pL->Q != b0 ); +// assert( pL->R != b0 ); +// assert( Cudd_bddIteConstant( dd, pL->Q, pL->R, b0 ) == b0 ); + assert( !Kit_TruthIsConst0(pIsfL->puOn, p->nVars) ); + assert( !Kit_TruthIsConst0(pIsfL->puOff, p->nVars) ); +// assert( Kit_TruthIsDisjoint(pIsfL->puOn, pIsfL->puOff, p->nVars) ); + + // derive the functions Q and R for the right branch +// Temp = Cudd_bddExistAbstract( dd, pF->R, pR->V ); Cudd_Ref( Temp ); +// pR->Q = Cudd_bddAndAbstract( dd, pF->Q, Temp, pL->V ); Cudd_Ref( pR->Q ); +// Cudd_RecursiveDeref( dd, Temp ); +// pR->R = Cudd_bddExistAbstract( dd, pF->R, pL->V ); Cudd_Ref( pR->R ); + + Kit_TruthAnd( pIsfR->puOn, pIsf->puOn, p->puTemp2, p->nVars ); + Kit_TruthExistSet( pIsfR->puOn, pIsfR->puOn, p->nVars, pIsfL->uUniq ); + Kit_TruthCopy( pIsfR->puOff, p->puTemp1, p->nVars ); + + assert( !Kit_TruthIsConst0(pIsfR->puOn, p->nVars) ); + assert( !Kit_TruthIsConst0(pIsfR->puOff, p->nVars) ); +// assert( Kit_TruthIsDisjoint(pIsfR->puOn, pIsfR->puOff, p->nVars) ); + + assert( pIsfL->uUniq ); + assert( pIsfR->uUniq ); + return Bdc_DecomposeGetCost( p, nLeftVars, nRightVars ); +} + +/**Function************************************************************* + + Synopsis [Performs one step of bi-decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bdc_Type_t Bdc_DecomposeStep( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Isf_t * pIsfL, Bdc_Isf_t * pIsfR ) +{ + int WeightOr, WeightAnd, WeightOrL, WeightOrR, WeightAndL, WeightAndR; + + Bdc_IsfClean( p->pIsfOL ); + Bdc_IsfClean( p->pIsfOR ); + Bdc_IsfClean( p->pIsfAL ); + Bdc_IsfClean( p->pIsfAR ); + + // perform OR decomposition + WeightOr = Bdc_DecomposeOr( p, pIsf, p->pIsfOL, p->pIsfOR ); + + // perform AND decomposition + Bdc_IsfNot( pIsf ); + WeightAnd = Bdc_DecomposeOr( p, pIsf, p->pIsfAL, p->pIsfAR ); + Bdc_IsfNot( pIsf ); + Bdc_IsfNot( p->pIsfAL ); + Bdc_IsfNot( p->pIsfAR ); + + // check the case when decomposition does not exist + if ( WeightOr == 0 && WeightAnd == 0 ) + { + Bdc_IsfCopy( pIsfL, p->pIsfOL ); + Bdc_IsfCopy( pIsfR, p->pIsfOR ); + return BDC_TYPE_MUX; + } + // check the hash table + assert( WeightOr || WeightAnd ); + WeightOrL = WeightOrR = 0; + if ( WeightOr ) + { + if ( p->pIsfOL->uUniq ) + { + Bdc_SuppMinimize( p, p->pIsfOL ); + WeightOrL = (Bdc_TableLookup(p, p->pIsfOL) != NULL); + } + if ( p->pIsfOR->uUniq ) + { + Bdc_SuppMinimize( p, p->pIsfOR ); + WeightOrR = (Bdc_TableLookup(p, p->pIsfOR) != NULL); + } + } + WeightAndL = WeightAndR = 0; + if ( WeightAnd ) + { + if ( p->pIsfAL->uUniq ) + { + Bdc_SuppMinimize( p, p->pIsfAL ); + WeightAndL = (Bdc_TableLookup(p, p->pIsfAL) != NULL); + } + if ( p->pIsfAR->uUniq ) + { + Bdc_SuppMinimize( p, p->pIsfAR ); + WeightAndR = (Bdc_TableLookup(p, p->pIsfAR) != NULL); + } + } + + // check if there is any reuse for the components + if ( WeightOrL + WeightOrR > WeightAndL + WeightAndR ) + { + p->numReuse++; + p->numOrs++; + Bdc_IsfCopy( pIsfL, p->pIsfOL ); + Bdc_IsfCopy( pIsfR, p->pIsfOR ); + return BDC_TYPE_OR; + } + if ( WeightOrL + WeightOrR < WeightAndL + WeightAndR ) + { + p->numReuse++; + p->numAnds++; + Bdc_IsfCopy( pIsfL, p->pIsfAL ); + Bdc_IsfCopy( pIsfR, p->pIsfAR ); + return BDC_TYPE_AND; + } + + // compare the two-component costs + if ( WeightOr > WeightAnd ) + { + if ( WeightOr < BDC_SCALE ) + p->numWeaks++; + p->numOrs++; + Bdc_IsfCopy( pIsfL, p->pIsfOL ); + Bdc_IsfCopy( pIsfR, p->pIsfOR ); + return BDC_TYPE_OR; + } + if ( WeightAnd < BDC_SCALE ) + p->numWeaks++; + p->numAnds++; + Bdc_IsfCopy( pIsfL, p->pIsfAL ); + Bdc_IsfCopy( pIsfR, p->pIsfAR ); + return BDC_TYPE_AND; +} + +/**Function************************************************************* + + Synopsis [Find variable that leads to minimum sum of support sizes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_DecomposeStepMux( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Isf_t * pIsfL, Bdc_Isf_t * pIsfR ) +{ + int Var, VarMin, nSuppMin, nSuppCur; + unsigned uSupp0, uSupp1; + int clk = 0; // Suppress "might be used uninitialized" + if ( p->pPars->fVerbose ) + clk = clock(); + VarMin = -1; + nSuppMin = 1000; + for ( Var = 0; Var < p->nVars; Var++ ) + { + if ( (pIsf->uSupp & (1 << Var)) == 0 ) + continue; + Kit_TruthCofactor0New( pIsfL->puOn, pIsf->puOn, p->nVars, Var ); + Kit_TruthCofactor0New( pIsfL->puOff, pIsf->puOff, p->nVars, Var ); + Kit_TruthCofactor1New( pIsfR->puOn, pIsf->puOn, p->nVars, Var ); + Kit_TruthCofactor1New( pIsfR->puOff, pIsf->puOff, p->nVars, Var ); + uSupp0 = Kit_TruthSupport( pIsfL->puOn, p->nVars ) & Kit_TruthSupport( pIsfL->puOff, p->nVars ); + uSupp1 = Kit_TruthSupport( pIsfR->puOn, p->nVars ) & Kit_TruthSupport( pIsfR->puOff, p->nVars ); + nSuppCur = Kit_WordCountOnes(uSupp0) + Kit_WordCountOnes(uSupp1); + if ( nSuppMin > nSuppCur ) + { + nSuppMin = nSuppCur; + VarMin = Var; + break; + } + } + if ( VarMin >= 0 ) + { + Kit_TruthCofactor0New( pIsfL->puOn, pIsf->puOn, p->nVars, VarMin ); + Kit_TruthCofactor0New( pIsfL->puOff, pIsf->puOff, p->nVars, VarMin ); + Kit_TruthCofactor1New( pIsfR->puOn, pIsf->puOn, p->nVars, VarMin ); + Kit_TruthCofactor1New( pIsfR->puOff, pIsf->puOff, p->nVars, VarMin ); + Bdc_SuppMinimize( p, pIsfL ); + Bdc_SuppMinimize( p, pIsfR ); + } + if ( p->pPars->fVerbose ) + p->timeMuxes += clock() - clk; + return VarMin; +} + +/**Function************************************************************* + + Synopsis [Creates gates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_ManNodeVerify( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Fun_t * pFunc ) +{ + unsigned * puTruth = p->puTemp1; + if ( Bdc_IsComplement(pFunc) ) + Kit_TruthNot( puTruth, Bdc_Regular(pFunc)->puFunc, p->nVars ); + else + Kit_TruthCopy( puTruth, pFunc->puFunc, p->nVars ); + return Bdc_TableCheckContainment( p, pIsf, puTruth ); +} + +/**Function************************************************************* + + Synopsis [Creates gates.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bdc_Fun_t * Bdc_ManCreateGate( Bdc_Man_t * p, Bdc_Fun_t * pFunc0, Bdc_Fun_t * pFunc1, Bdc_Type_t Type ) +{ + Bdc_Fun_t * pFunc; + pFunc = Bdc_FunNew( p ); + if ( pFunc == NULL ) + return NULL; + pFunc->Type = Type; + pFunc->pFan0 = pFunc0; + pFunc->pFan1 = pFunc1; + pFunc->puFunc = (unsigned *)Vec_IntFetch(p->vMemory, p->nWords); + // get the truth table of the left branch + if ( Bdc_IsComplement(pFunc0) ) + Kit_TruthNot( p->puTemp1, Bdc_Regular(pFunc0)->puFunc, p->nVars ); + else + Kit_TruthCopy( p->puTemp1, pFunc0->puFunc, p->nVars ); + // get the truth table of the right branch + if ( Bdc_IsComplement(pFunc1) ) + Kit_TruthNot( p->puTemp2, Bdc_Regular(pFunc1)->puFunc, p->nVars ); + else + Kit_TruthCopy( p->puTemp2, pFunc1->puFunc, p->nVars ); + // compute the function of node + if ( pFunc->Type == BDC_TYPE_AND ) + { + Kit_TruthAnd( pFunc->puFunc, p->puTemp1, p->puTemp2, p->nVars ); + } + else if ( pFunc->Type == BDC_TYPE_OR ) + { + Kit_TruthOr( pFunc->puFunc, p->puTemp1, p->puTemp2, p->nVars ); + // transform to AND gate + pFunc->Type = BDC_TYPE_AND; + pFunc->pFan0 = Bdc_Not(pFunc->pFan0); + pFunc->pFan1 = Bdc_Not(pFunc->pFan1); + Kit_TruthNot( pFunc->puFunc, pFunc->puFunc, p->nVars ); + pFunc = Bdc_Not(pFunc); + } + else + assert( 0 ); + // add to table + Bdc_Regular(pFunc)->uSupp = Kit_TruthSupport( Bdc_Regular(pFunc)->puFunc, p->nVars ); + Bdc_TableAdd( p, Bdc_Regular(pFunc) ); + return pFunc; +} + +/**Function************************************************************* + + Synopsis [Performs one step of bi-decomposition.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bdc_Fun_t * Bdc_ManDecompose_rec( Bdc_Man_t * p, Bdc_Isf_t * pIsf ) +{ +// int static Counter = 0; +// int LocalCounter = Counter++; + Bdc_Type_t Type; + Bdc_Fun_t * pFunc, * pFunc0, * pFunc1; + Bdc_Isf_t IsfL, * pIsfL = &IsfL; + Bdc_Isf_t IsfB, * pIsfR = &IsfB; + int iVar; + int clk = 0; // Suppress "might be used uninitialized" +/* +printf( "Init function (%d):\n", LocalCounter ); +Extra_PrintBinary( stdout, pIsf->puOn, 1<<4 );printf("\n"); +Extra_PrintBinary( stdout, pIsf->puOff, 1<<4 );printf("\n"); +*/ + // check computed results + assert( Kit_TruthIsDisjoint(pIsf->puOn, pIsf->puOff, p->nVars) ); + if ( p->pPars->fVerbose ) + clk = clock(); + pFunc = Bdc_TableLookup( p, pIsf ); + if ( p->pPars->fVerbose ) + p->timeCache += clock() - clk; + if ( pFunc ) + return pFunc; + // decide on the decomposition type + if ( p->pPars->fVerbose ) + clk = clock(); + Type = Bdc_DecomposeStep( p, pIsf, pIsfL, pIsfR ); + if ( p->pPars->fVerbose ) + p->timeCheck += clock() - clk; + if ( Type == BDC_TYPE_MUX ) + { + if ( p->pPars->fVerbose ) + clk = clock(); + iVar = Bdc_DecomposeStepMux( p, pIsf, pIsfL, pIsfR ); + if ( p->pPars->fVerbose ) + p->timeMuxes += clock() - clk; + p->numMuxes++; + pFunc0 = Bdc_ManDecompose_rec( p, pIsfL ); + pFunc1 = Bdc_ManDecompose_rec( p, pIsfR ); + if ( pFunc0 == NULL || pFunc1 == NULL ) + return NULL; + pFunc = Bdc_FunWithId( p, iVar + 1 ); + pFunc0 = Bdc_ManCreateGate( p, Bdc_Not(pFunc), pFunc0, BDC_TYPE_AND ); + pFunc1 = Bdc_ManCreateGate( p, pFunc, pFunc1, BDC_TYPE_AND ); + if ( pFunc0 == NULL || pFunc1 == NULL ) + return NULL; + pFunc = Bdc_ManCreateGate( p, pFunc0, pFunc1, BDC_TYPE_OR ); + } + else + { + pFunc0 = Bdc_ManDecompose_rec( p, pIsfL ); + if ( pFunc0 == NULL ) + return NULL; + // decompose the right branch + if ( Bdc_DecomposeUpdateRight( p, pIsf, pIsfL, pIsfR, pFunc0, Type ) ) + { + p->nNodesNew--; + return pFunc0; + } + Bdc_SuppMinimize( p, pIsfR ); + pFunc1 = Bdc_ManDecompose_rec( p, pIsfR ); + if ( pFunc1 == NULL ) + return NULL; + // create new gate + pFunc = Bdc_ManCreateGate( p, pFunc0, pFunc1, Type ); + } + return pFunc; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/bool/bdc/bdcInt.h b/src/bool/bdc/bdcInt.h new file mode 100644 index 00000000..05ce20b6 --- /dev/null +++ b/src/bool/bdc/bdcInt.h @@ -0,0 +1,165 @@ +/**CFile**************************************************************** + + FileName [bdcInt.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Truth-table-based bi-decomposition engine.] + + Synopsis [Internal declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 15, 2007.] + + Revision [$Id: resInt.h,v 1.00 2007/01/15 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__aig__bdc__bdcInt_h +#define ABC__aig__bdc__bdcInt_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "src/bool/kit/kit.h" +#include "bdc.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_HEADER_START + + +#define BDC_SCALE 1000 // value used to compute the cost + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// network types +typedef enum { + BDC_TYPE_NONE = 0, // 0: unknown + BDC_TYPE_CONST1, // 1: constant 1 + BDC_TYPE_PI, // 2: primary input + BDC_TYPE_AND, // 3: AND-gate + BDC_TYPE_OR, // 4: OR-gate (temporary) + BDC_TYPE_XOR, // 5: XOR-gate + BDC_TYPE_MUX, // 6: MUX-gate + BDC_TYPE_OTHER // 7: unused +} Bdc_Type_t; + +struct Bdc_Fun_t_ +{ + int Type; // Const1, PI, AND, XOR, MUX + Bdc_Fun_t * pFan0; // fanin of the given node + Bdc_Fun_t * pFan1; // fanin of the given node + unsigned uSupp; // bit mask of current support + unsigned * puFunc; // the function of the node + Bdc_Fun_t * pNext; // next function with same support + union { int iCopy; // the literal of the node (AIG) + void * pCopy; }; // the function of the node (BDD or AIG) + +}; + +typedef struct Bdc_Isf_t_ Bdc_Isf_t; +struct Bdc_Isf_t_ +{ + unsigned uSupp; // the complete support of this component + unsigned uUniq; // the unique variables of this component + unsigned * puOn; // on-set + unsigned * puOff; // off-set +}; + +struct Bdc_Man_t_ +{ + // external parameters + Bdc_Par_t * pPars; // parameter set + int nVars; // the number of variables + int nWords; // the number of words + int nNodesMax; // the limit on the number of new nodes + int nDivsLimit; // the limit on the number of divisors + // internal nodes + Bdc_Fun_t * pNodes; // storage for decomposition nodes + int nNodesAlloc; // the number of nodes allocated + int nNodes; // the number of all nodes created so far + int nNodesNew; // the number of new AND nodes created so far + Bdc_Fun_t * pRoot; // the root node + // resub candidates + Bdc_Fun_t ** pTable; // hash table of candidates + int nTableSize; // hash table size (1 << nVarsMax) + Vec_Int_t * vSpots; // the occupied spots in the table + // elementary truth tables + Vec_Ptr_t * vTruths; // for const 1 and elementary variables + unsigned * puTemp1; // temporary truth table + unsigned * puTemp2; // temporary truth table + unsigned * puTemp3; // temporary truth table + unsigned * puTemp4; // temporary truth table + // temporary ISFs + Bdc_Isf_t * pIsfOL, IsfOL; + Bdc_Isf_t * pIsfOR, IsfOR; + Bdc_Isf_t * pIsfAL, IsfAL; + Bdc_Isf_t * pIsfAR, IsfAR; + // internal memory manager + Vec_Int_t * vMemory; // memory for internal truth tables + // statistics + int numCalls; + int numNodes; + int numMuxes; + int numAnds; + int numOrs; + int numWeaks; + int numReuse; + // runtime + int timeCache; + int timeCheck; + int timeMuxes; + int timeSupps; + int timeTotal; +}; + +static inline Bdc_Fun_t * Bdc_FunNew( Bdc_Man_t * p ) { Bdc_Fun_t * pRes; if ( p->nNodes >= p->nNodesAlloc || p->nNodesNew >= p->nNodesMax ) return NULL; pRes = p->pNodes + p->nNodes++; p->nNodesNew++; memset( pRes, 0, sizeof(Bdc_Fun_t) ); return pRes; } +static inline Bdc_Fun_t * Bdc_FunWithId( Bdc_Man_t * p, int Id ) { assert( Id < p->nNodes ); return p->pNodes + Id; } +static inline int Bdc_FunId( Bdc_Man_t * p, Bdc_Fun_t * pFun ) { return pFun - p->pNodes; } +static inline void Bdc_IsfStart( Bdc_Man_t * p, Bdc_Isf_t * pF ) { pF->uSupp = 0; pF->uUniq = 0; pF->puOn = Vec_IntFetch( p->vMemory, p->nWords ); pF->puOff = Vec_IntFetch( p->vMemory, p->nWords ); assert( pF->puOff && pF->puOn ); } +static inline void Bdc_IsfClean( Bdc_Isf_t * p ) { p->uSupp = 0; p->uUniq = 0; } +static inline void Bdc_IsfCopy( Bdc_Isf_t * p, Bdc_Isf_t * q ) { Bdc_Isf_t T = *p; *p = *q; *q = T; } +static inline void Bdc_IsfNot( Bdc_Isf_t * p ) { unsigned * puT = p->puOn; p->puOn = p->puOff; p->puOff = puT; } + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/*=== bdcDec.c ==========================================================*/ +extern Bdc_Fun_t * Bdc_ManDecompose_rec( Bdc_Man_t * p, Bdc_Isf_t * pIsf ); +extern void Bdc_SuppMinimize( Bdc_Man_t * p, Bdc_Isf_t * pIsf ); +extern int Bdc_ManNodeVerify( Bdc_Man_t * p, Bdc_Isf_t * pIsf, Bdc_Fun_t * pFunc ); +/*=== bdcTable.c ==========================================================*/ +extern Bdc_Fun_t * Bdc_TableLookup( Bdc_Man_t * p, Bdc_Isf_t * pIsf ); +extern void Bdc_TableAdd( Bdc_Man_t * p, Bdc_Fun_t * pFunc ); +extern void Bdc_TableClear( Bdc_Man_t * p ); +extern int Bdc_TableCheckContainment( Bdc_Man_t * p, Bdc_Isf_t * pIsf, unsigned * puTruth ); + + + +ABC_NAMESPACE_HEADER_END + + + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/bool/bdc/bdcSpfd.c b/src/bool/bdc/bdcSpfd.c new file mode 100644 index 00000000..83a35c11 --- /dev/null +++ b/src/bool/bdc/bdcSpfd.c @@ -0,0 +1,1176 @@ +/**CFile**************************************************************** + + FileName [bdcSpfd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Truth-table-based bi-decomposition engine.] + + Synopsis [The gateway to bi-decomposition.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 30, 2007.] + + Revision [$Id: bdcSpfd.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bdcInt.h" +#include "src/aig/aig/aig.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Bdc_Nod_t_ Bdc_Nod_t; +struct Bdc_Nod_t_ +{ + unsigned iFan0g : 8; + unsigned iFan0n : 12; + unsigned Type : 12; // 0-3 = AND; 4 = XOR + + unsigned iFan1g : 8; + unsigned iFan1n : 12; + unsigned Weight : 12; + + word Truth; +}; + +static word Truths[6] = { + 0xAAAAAAAAAAAAAAAA, + 0xCCCCCCCCCCCCCCCC, + 0xF0F0F0F0F0F0F0F0, + 0xFF00FF00FF00FF00, + 0xFFFF0000FFFF0000, + 0xFFFFFFFF00000000 +}; + +static inline int Bdc_CountOnes( word t ) +{ + t = (t & 0x5555555555555555) + ((t>> 1) & 0x5555555555555555); + t = (t & 0x3333333333333333) + ((t>> 2) & 0x3333333333333333); + t = (t & 0x0F0F0F0F0F0F0F0F) + ((t>> 4) & 0x0F0F0F0F0F0F0F0F); + t = (t & 0x00FF00FF00FF00FF) + ((t>> 8) & 0x00FF00FF00FF00FF); + t = (t & 0x0000FFFF0000FFFF) + ((t>>16) & 0x0000FFFF0000FFFF); + return (t & 0x00000000FFFFFFFF) + (t>>32); +} + +static inline int Bdc_CountSpfd( word t, word f ) +{ + int n00 = Bdc_CountOnes( ~t & ~f ); + int n01 = Bdc_CountOnes( t & ~f ); + int n10 = Bdc_CountOnes( ~t & f ); + int n11 = Bdc_CountOnes( t & f ); + return n00 * n11 + n10 * n01; +} + +static inline word Bdc_Cof6( word t, int iVar, int fCof1 ) +{ + assert( iVar >= 0 && iVar < 6 ); + if ( fCof1 ) + return (t & Truths[iVar]) | ((t & Truths[iVar]) >> (1<<iVar)); + else + return (t &~Truths[iVar]) | ((t &~Truths[iVar]) << (1<<iVar)); +} + +int Bdc_SpfdAdjCost( word t ) +{ + word c0, c1; + int v, Cost = 0; + for ( v = 0; v < 6; v++ ) + { + c0 = Bdc_Cof6( t, v, 0 ); + c1 = Bdc_Cof6( t, v, 1 ); + Cost += Bdc_CountOnes( c0 ^ c1 ); + } + return Cost; +} + + +extern void Abc_Show6VarFunc( word F0, word F1 ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdPrint_rec( Bdc_Nod_t * pNode, int Level, Vec_Ptr_t * vLevels ) +{ + assert( Level > 0 ); + printf( "(" ); + + if ( pNode->Type & 1 ) + printf( "!" ); + if ( pNode->iFan0g == 0 ) + printf( "%c", 'a' + pNode->iFan0n ); + else + { + Bdc_Nod_t * pNode0 = (Bdc_Nod_t *)Vec_PtrEntry(vLevels, pNode->iFan0g); + Bdc_SpfdPrint_rec( pNode0 + pNode->iFan0n, pNode->iFan0g, vLevels ); + } + + if ( pNode->Type & 4 ) + printf( "+" ); + else + printf( "*" ); + + if ( pNode->Type & 2 ) + printf( "!" ); + if ( pNode->iFan1g == 0 ) + printf( "%c", 'a' + pNode->iFan1n ); + else + { + Bdc_Nod_t * pNode1 = (Bdc_Nod_t *)Vec_PtrEntry(vLevels, pNode->iFan1g); + Bdc_SpfdPrint_rec( pNode1 + pNode->iFan1n, pNode->iFan1g, vLevels ); + } + + printf( ")" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdPrint( Bdc_Nod_t * pNode, int Level, Vec_Ptr_t * vLevels, word Truth ) +{ + word Diff = Truth ^ pNode->Truth; + Extra_PrintHex( stdout, (unsigned *)&pNode->Truth, 6 ); printf( " " ); + Extra_PrintHex( stdout, (unsigned *)&Diff, 6 ); printf( " " ); + Bdc_SpfdPrint_rec( pNode, Level, vLevels ); + printf( " %d\n", pNode->Weight ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdDecompose( word Truth, int nVars, int nCands, int nGatesMax ) +{ + int nSize = nCands * nCands * (nGatesMax + 1) * 5; + Vec_Ptr_t * vLevels; + Vec_Int_t * vBegs, * vWeight; + Bdc_Nod_t * pNode, * pNode0, * pNode1, * pNode2; + int Count0, Count1, * pPerm; + int i, j, k, c, n, clk; + assert( nGatesMax < (1<<8) ); + assert( nCands < (1<<12) ); + assert( (1<<(nVars-1))*(1<<(nVars-1)) < (1<<12) ); // max SPFD + + printf( "Storage size = %d (%d * %d * %d * %d).\n", nSize, nCands, nCands, nGatesMax + 1, 5 ); + + printf( "SPFD = %d.\n", Bdc_CountOnes(Truth) * Bdc_CountOnes(~Truth) ); + + // consider elementary functions + if ( Truth == 0 || Truth == ~0 ) + { + printf( "Function is a constant.\n" ); + return; + } + for ( i = 0; i < nVars; i++ ) + if ( Truth == Truths[i] || Truth == ~Truths[i] ) + { + printf( "Function is an elementary variable.\n" ); + return; + } + + // allocate + vLevels = Vec_PtrAlloc( 100 ); + vBegs = Vec_IntAlloc( 100 ); + vWeight = Vec_IntAlloc( 100 ); + + // initialize elementary variables + pNode = ABC_CALLOC( Bdc_Nod_t, nVars ); + for ( i = 0; i < nVars; i++ ) + pNode[i].Truth = Truths[i]; + for ( i = 0; i < nVars; i++ ) + pNode[i].Weight = Bdc_CountSpfd( pNode[i].Truth, Truth ); + Vec_PtrPush( vLevels, pNode ); + Vec_IntPush( vBegs, nVars ); + + // the next level +clk = clock(); + pNode0 = pNode; + pNode = ABC_CALLOC( Bdc_Nod_t, 5 * nVars * (nVars - 1) / 2 ); + for ( c = i = 0; i < nVars; i++ ) + for ( j = i+1; j < nVars; j++ ) + { + pNode[c].Truth = pNode0[i].Truth & pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 0; + pNode[c].Truth = ~pNode0[i].Truth & pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 1; + pNode[c].Truth = pNode0[i].Truth & ~pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 2; + pNode[c].Truth = ~pNode0[i].Truth & ~pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 3; + pNode[c].Truth = pNode0[i].Truth ^ pNode0[j].Truth; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 4; + } + assert( c == 5 * nVars * (nVars - 1) / 2 ); + Vec_PtrPush( vLevels, pNode ); + Vec_IntPush( vBegs, c ); + for ( i = 0; i < c; i++ ) + { + pNode[i].Weight = Bdc_CountSpfd( pNode[i].Truth, Truth ); +//Bdc_SpfdPrint( pNode + i, 1, vLevels ); + if ( Truth == pNode[i].Truth || Truth == ~pNode[i].Truth ) + { + printf( "Function can be implemented using 1 gate.\n" ); + pNode = NULL; + goto cleanup; + } + } +printf( "Selected %6d gates on level %2d. ", c, 1 ); +Abc_PrintTime( 1, "Time", clock() - clk ); + + + // iterate through levels + pNode = ABC_CALLOC( Bdc_Nod_t, nSize ); + for ( n = 2; n <= nGatesMax; n++ ) + { +clk = clock(); + c = 0; + pNode1 = (Bdc_Nod_t *)Vec_PtrEntry( vLevels, n-1 ); + Count1 = Vec_IntEntry( vBegs, n-1 ); + // go through previous levels + for ( k = 0; k < n-1; k++ ) + { + pNode0 = (Bdc_Nod_t *)Vec_PtrEntry( vLevels, k ); + Count0 = Vec_IntEntry( vBegs, k ); + for ( i = 0; i < Count0; i++ ) + for ( j = 0; j < Count1; j++ ) + { + pNode[c].Truth = pNode0[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 0; + pNode[c].Truth = ~pNode0[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 1; + pNode[c].Truth = pNode0[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 2; + pNode[c].Truth = ~pNode0[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 3; + pNode[c].Truth = pNode0[i].Truth ^ pNode1[j].Truth; pNode[c].iFan0g = k; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 4; + } + assert( c < nSize ); + } + // go through current level + for ( i = 0; i < Count1; i++ ) + for ( j = i+1; j < Count1; j++ ) + { + pNode[c].Truth = pNode1[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 0; + pNode[c].Truth = ~pNode1[i].Truth & pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 1; + pNode[c].Truth = pNode1[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 2; + pNode[c].Truth = ~pNode1[i].Truth & ~pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 3; + pNode[c].Truth = pNode1[i].Truth ^ pNode1[j].Truth; pNode[c].iFan0g = n-1; pNode[c].iFan1g = n-1; pNode[c].iFan0n = i; pNode[c].iFan1n = j; pNode[c++].Type = 4; + } + assert( c < nSize ); + // sort + Vec_IntClear( vWeight ); + for ( i = 0; i < c; i++ ) + { + pNode[i].Weight = Bdc_CountSpfd( pNode[i].Truth, Truth ); +if ( pNode[i].Weight > 300 ) +Bdc_SpfdPrint( pNode + i, 1, vLevels, Truth ); + Vec_IntPush( vWeight, pNode[i].Weight ); + + if ( Truth == pNode[i].Truth || Truth == ~pNode[i].Truth ) + { + printf( "Function can be implemented using %d gates.\n", n ); + Bdc_SpfdPrint( pNode + i, n, vLevels, Truth ); + goto cleanup; + } + } + pPerm = Abc_SortCost( Vec_IntArray(vWeight), c ); + assert( Vec_IntEntry(vWeight, pPerm[0]) <= Vec_IntEntry(vWeight, pPerm[c-1]) ); + + printf( "Best SPFD = %d.\n", Vec_IntEntry(vWeight, pPerm[c-1]) ); +// for ( i = 0; i < c; i++ ) +//printf( "%d ", Vec_IntEntry(vWeight, pPerm[i]) ); + + // choose the best ones + pNode2 = ABC_CALLOC( Bdc_Nod_t, nCands ); + for ( j = 0, i = c-1; i >= 0; i-- ) + { + pNode2[j++] = pNode[pPerm[i]]; + if ( j == nCands ) + break; + } + ABC_FREE( pPerm ); + Vec_PtrPush( vLevels, pNode2 ); + Vec_IntPush( vBegs, j ); + +printf( "Selected %6d gates (out of %6d) on level %2d. ", j, c, n ); +Abc_PrintTime( 1, "Time", clock() - clk ); + + for ( i = 0; i < 10; i++ ) + Bdc_SpfdPrint( pNode2 + i, n, vLevels, Truth ); + } + +cleanup: + ABC_FREE( pNode ); + Vec_PtrForEachEntry( Bdc_Nod_t *, vLevels, pNode, i ) + ABC_FREE( pNode ); + Vec_PtrFree( vLevels ); + Vec_IntFree( vBegs ); + Vec_IntFree( vWeight ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdDecomposeTest_() +{ + int fTry = 0; +// word T[17]; +// int i; + +// word Truth = Truths[0] & ~Truths[3]; +// word Truth = (Truths[0] & Truths[1]) | (Truths[2] & Truths[3]) | (Truths[4] & Truths[5]); +// word Truth = (Truths[0] & Truths[1]) | ((Truths[2] & ~Truths[3]) ^ (Truths[4] & ~Truths[5])); +// word Truth = (Truths[0] & Truths[1]) | (Truths[2] & Truths[3]); +// word Truth = 0x9ef7a8d9c7193a0f; // AAFFAAFF0A0F0A0F +// word Truth = 0x34080226CD163000; + word Truth = 0x5052585a0002080a; + int nVars = 6; + int nCands = 200;// 75; + int nGatesMax = 20; + + if ( fTry ) + Bdc_SpfdDecompose( Truth, nVars, nCands, nGatesMax ); +/* + for ( i = 0; i < 6; i++ ) + T[i] = Truths[i]; + T[7] = 0; + T[8] = ~T[1] & T[3]; + T[9] = ~T[8] & T[0]; + T[10] = T[1] & T[4]; + T[11] = T[10] & T[2]; + T[12] = T[11] & T[9]; + T[13] = ~T[0] & T[5]; + T[14] = T[2] & T[13]; + T[15] = ~T[12] & ~T[14]; + T[16] = ~T[15]; +// if ( T[16] != Truth ) +// printf( "Failed\n" ); + + for ( i = 0; i < 17; i++ ) + { +// printf( "%2d = %3d ", i, Bdc_CountSpfd(T[i], Truth) ); + printf( "%2d = %3d ", i, Bdc_CountSpfd(T[i], T[16]) ); + Extra_PrintBinary( stdout, (unsigned *)&T[i], 64 ); printf( "\n" ); + } +// Extra_PrintBinary( stdout, (unsigned *)&Truth, 64 ); printf( "\n" ); +*/ +} + + + + +typedef struct Bdc_Ent_t_ Bdc_Ent_t; // 24 bytes +struct Bdc_Ent_t_ +{ + unsigned iFan0 : 29; + unsigned fCompl0 : 1; + unsigned fCompl : 1; + unsigned fMark0 : 1; + unsigned iFan1 : 29; + unsigned fCompl1 : 1; + unsigned fExor : 1; + unsigned fMark1 : 1; + int iNext; + int iList; + word Truth; +}; + +#define BDC_TERM 0x1FFFFFFF + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_SpfdMark0( Bdc_Ent_t * p, Bdc_Ent_t * pEnt ) +{ + if ( pEnt->iFan0 == BDC_TERM ) + return 0; + if ( pEnt->fMark0 ) + return 0; + pEnt->fMark0 = 1; + return pEnt->fMark1 + + Bdc_SpfdMark0(p, p + pEnt->iFan0) + + Bdc_SpfdMark0(p, p + pEnt->iFan1); +} +int Bdc_SpfdMark1( Bdc_Ent_t * p, Bdc_Ent_t * pEnt ) +{ + if ( pEnt->iFan0 == BDC_TERM ) + return 0; + if ( pEnt->fMark1 ) + return 0; + pEnt->fMark1 = 1; + return pEnt->fMark0 + + Bdc_SpfdMark1(p, p + pEnt->iFan0) + + Bdc_SpfdMark1(p, p + pEnt->iFan1); +} +void Bdc_SpfdUnmark0( Bdc_Ent_t * p, Bdc_Ent_t * pEnt ) +{ + if ( pEnt->iFan0 == BDC_TERM ) + return; + pEnt->fMark0 = 0; + Bdc_SpfdUnmark0( p, p + pEnt->iFan0 ); + Bdc_SpfdUnmark0( p, p + pEnt->iFan1 ); +} +void Bdc_SpfdUnmark1( Bdc_Ent_t * p, Bdc_Ent_t * pEnt ) +{ + if ( pEnt->iFan0 == BDC_TERM ) + return; + pEnt->fMark1 = 0; + Bdc_SpfdUnmark1( p, p + pEnt->iFan0 ); + Bdc_SpfdUnmark1( p, p + pEnt->iFan1 ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_SpfdCheckOverlap( Bdc_Ent_t * p, Bdc_Ent_t * pEnt0, Bdc_Ent_t * pEnt1 ) +{ + int RetValue; + RetValue = Bdc_SpfdMark0( p, pEnt0 ); + assert( RetValue == 0 ); + RetValue = Bdc_SpfdMark1( p, pEnt1 ); + Bdc_SpfdUnmark0( p, pEnt0 ); + Bdc_SpfdUnmark1( p, pEnt1 ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_SpfdHashValue( word t, int Size ) +{ + // http://planetmath.org/encyclopedia/GoodHashTablePrimes.html + // 53, + // 97, + // 193, + // 389, + // 769, + // 1543, + // 3079, + // 6151, + // 12289, + // 24593, + // 49157, + // 98317, + // 196613, + // 393241, + // 786433, + // 1572869, + // 3145739, + // 6291469, + // 12582917, + // 25165843, + // 50331653, + // 100663319, + // 201326611, + // 402653189, + // 805306457, + // 1610612741, + static unsigned BigPrimes[8] = {12582917, 25165843, 50331653, 100663319, 201326611, 402653189, 805306457, 1610612741}; + unsigned char * s = (unsigned char *)&t; + unsigned i, Value = 0; + for ( i = 0; i < 8; i++ ) + Value ^= BigPrimes[i] * s[i]; + return Value % Size; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Bdc_SpfdHashLookup( Bdc_Ent_t * p, int Size, word t ) +{ + Bdc_Ent_t * pBin = p + Bdc_SpfdHashValue( t, Size ); + if ( pBin->iList == 0 ) + return &pBin->iList; + for ( pBin = p + pBin->iList; ; pBin = p + pBin->iNext ) + { + if ( pBin->Truth == t ) + return NULL; + if ( pBin->iNext == 0 ) + return &pBin->iNext; + } + assert( 0 ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Bdc_SpfdDecomposeTest__( Vec_Int_t ** pvWeights ) +{ +// int nFuncs = 8000000; // the number of functions to compute +// int nSize = 2777111; // the hash table size to use +// int Limit = 6; + +// int nFuncs = 51000000; // the number of functions to compute +// int nSize = 50331653; // the hash table size to use +// int Limit = 6; + + int nFuncs = 250000000; // the number of functions to compute + int nSize = 201326611; // the hash table size to use + int Limit = 6; + + int * pPlace, i, n, m, k, s, fCompl, clk = clock(), clk2; + Vec_Int_t * vStops; + Vec_Wrd_t * vTruths; + Vec_Int_t * vWeights; + Bdc_Ent_t * p, * q, * pBeg0, * pEnd0, * pBeg1, * pEnd1, * pThis0, * pThis1; + word t0, t1, t; + assert( nSize <= nFuncs ); + + printf( "Allocating %.2f Mb of internal memory.\n", 1.0*sizeof(Bdc_Ent_t)*nFuncs/(1<<20) ); + + p = (Bdc_Ent_t *)calloc( nFuncs, sizeof(Bdc_Ent_t) ); + memset( p, 255, sizeof(Bdc_Ent_t) ); + p->iList = 0; + for ( q = p; q < p+nFuncs; q++ ) + q->iList = 0; + q = p + 1; + printf( "Added %d + %d + 0 = %d. Total = %8d.\n", 0, 0, 0, q-p ); + + vTruths = Vec_WrdStart( nFuncs ); + vWeights = Vec_IntStart( nFuncs ); + Vec_WrdClear( vTruths ); + Vec_IntClear( vWeights ); + + // create elementary vars + vStops = Vec_IntAlloc( 10 ); + Vec_IntPush( vStops, 1 ); + for ( i = 0; i < 6; i++ ) + { + q->iFan0 = BDC_TERM; + q->iFan1 = i; + q->Truth = Truths[i]; + pPlace = Bdc_SpfdHashLookup( p, nSize, q->Truth ); + *pPlace = q-p; + q++; + Vec_WrdPush( vTruths, Truths[i] ); + Vec_IntPush( vWeights, 0 ); + } + Vec_IntPush( vStops, 7 ); + printf( "Added %d + %d + 0 = %d. Total = %8d.\n", 0, 0, 0, q-p ); + + // create gates + for ( n = 0; n < Limit; n++ ) + { + // try previous + for ( k = 0; k < Limit; k++ ) + for ( m = 0; m < Limit; m++ ) + { + if ( k + m != n || k > m ) + continue; + // set the start and stop + pBeg0 = p + Vec_IntEntry( vStops, k ); + pEnd0 = p + Vec_IntEntry( vStops, k+1 ); + // set the start and stop + pBeg1 = p + Vec_IntEntry( vStops, m ); + pEnd1 = p + Vec_IntEntry( vStops, m+1 ); + + clk2 = clock(); + printf( "Trying %7d x %7d. ", pEnd0-pBeg0, pEnd1-pBeg1 ); + for ( pThis0 = pBeg0; pThis0 < pEnd0; pThis0++ ) + for ( pThis1 = pBeg1; pThis1 < pEnd1; pThis1++ ) + if ( k < m || pThis1 > pThis0 ) +// if ( n < 5 || Bdc_SpfdCheckOverlap(p, pThis0, pThis1) ) + for ( s = 0; s < 5; s++ ) + { + t0 = (s&1) ? ~pThis0->Truth : pThis0->Truth; + t1 = ((s>>1)&1) ? ~pThis1->Truth : pThis1->Truth; + t = ((s>>2)&1) ? t0 ^ t1 : t0 & t1; + fCompl = t & 1; + if ( fCompl ) + t = ~t; + if ( t == 0 ) + continue; + pPlace = Bdc_SpfdHashLookup( p, nSize, t ); + if ( pPlace == NULL ) + continue; + q->iFan0 = pThis0-p; + q->fCompl0 = s&1; + q->iFan1 = pThis1-p; + q->fCompl1 = (s>>1)&1; + q->fExor = (s>>2)&1; + q->Truth = t; + q->fCompl = fCompl; + *pPlace = q-p; + q++; + Vec_WrdPush( vTruths, t ); +// Vec_IntPush( vWeights, n == 5 ? n : n+1 ); + Vec_IntPush( vWeights, n+1 ); + if ( q-p == nFuncs ) + { + printf( "Reached limit of %d functions.\n", nFuncs ); + goto finish; + } + } + printf( "Added %d + %d + 1 = %d. Total = %8d. ", k, m, n+1, q-p ); + Abc_PrintTime( 1, "Time", clock() - clk2 ); + } + Vec_IntPush( vStops, q-p ); + } + Abc_PrintTime( 1, "Time", clock() - clk ); + + + { + FILE * pFile = fopen( "func6v6n_bin.txt", "wb" ); + fwrite( Vec_WrdArray(vTruths), sizeof(word), Vec_WrdSize(vTruths), pFile ); + fclose( pFile ); + } + { + FILE * pFile = fopen( "func6v6nW_bin.txt", "wb" ); + fwrite( Vec_IntArray(vWeights), sizeof(int), Vec_IntSize(vWeights), pFile ); + fclose( pFile ); + } + + +finish: + Vec_IntFree( vStops ); + free( p ); + + *pvWeights = vWeights; +// Vec_WrdFree( vTruths ); + return vTruths; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Bdc_SpfdReadFiles5( Vec_Int_t ** pvWeights ) +{ + Vec_Int_t * vWeights; + Vec_Wrd_t * vDivs; + FILE * pFile; + + vDivs = Vec_WrdStart( 3863759 ); + pFile = fopen( "func6v5n_bin.txt", "rb" ); + fread( Vec_WrdArray(vDivs), sizeof(word), Vec_WrdSize(vDivs), pFile ); + fclose( pFile ); + + vWeights = Vec_IntStart( 3863759 ); + pFile = fopen( "func6v5nW_bin.txt", "rb" ); + fread( Vec_IntArray(vWeights), sizeof(int), Vec_IntSize(vWeights), pFile ); + fclose( pFile ); + + *pvWeights = vWeights; + return vDivs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Bdc_SpfdReadFiles6( Vec_Int_t ** pvWeights ) +{ + Vec_Int_t * vWeights; + Vec_Wrd_t * vDivs = Vec_WrdStart( 12776759 ); + FILE * pFile = fopen( "func6v6n_bin.txt", "rb" ); + fread( Vec_WrdArray(vDivs), sizeof(word), Vec_WrdSize(vDivs), pFile ); + fclose( pFile ); + + vWeights = Vec_IntStart( 12776759 ); + pFile = fopen( "func6v6nW_bin.txt", "rb" ); + fread( Vec_IntArray(vWeights), sizeof(int), Vec_IntSize(vWeights), pFile ); + fclose( pFile ); + + *pvWeights = vWeights; + return vDivs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_SpfdComputeCost( word f, int i, Vec_Int_t * vWeights ) +{ + int Ones = Bdc_CountOnes(f); + if ( Ones == 0 ) + return -1; + return 7*Ones + 10*(8 - Vec_IntEntry(vWeights, i)); +// return Bdc_CountOnes(f); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word Bdc_SpfdFindBest( Vec_Wrd_t * vDivs, Vec_Int_t * vWeights, word F0, word F1, int * pCost ) +{ + word Func, FuncBest; + int i, Cost, CostBest = -1, NumBest; + Vec_WrdForEachEntry( vDivs, Func, i ) + { + if ( (Func & F0) == 0 ) + { + Cost = Bdc_SpfdComputeCost(Func & F1, i, vWeights); + if ( CostBest < Cost ) + { + CostBest = Cost; + FuncBest = Func; + NumBest = i; + } + } + if ( (Func & F1) == 0 ) + { + Cost = Bdc_SpfdComputeCost(Func & F0, i, vWeights); + if ( CostBest < Cost ) + { + CostBest = Cost; + FuncBest = Func; + NumBest = i; + } + } + if ( (~Func & F0) == 0 ) + { + Cost = Bdc_SpfdComputeCost(~Func & F1, i, vWeights); + if ( CostBest < Cost ) + { + CostBest = Cost; + FuncBest = ~Func; + NumBest = i; + } + } + if ( (~Func & F1) == 0 ) + { + Cost = Bdc_SpfdComputeCost(~Func & F0, i, vWeights); + if ( CostBest < Cost ) + { + CostBest = Cost; + FuncBest = ~Func; + NumBest = i; + } + } + } + (*pCost) += Vec_IntEntry(vWeights, NumBest); + assert( CostBest > 0 ); + printf( "Selected %8d with cost %2d and weight %d: ", NumBest, 0, Vec_IntEntry(vWeights, NumBest) ); + Extra_PrintHex( stdout, (unsigned *)&FuncBest, 6 ); printf( "\n" ); + return FuncBest; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_SpfdDecomposeTestOne( word t, Vec_Wrd_t * vDivs, Vec_Int_t * vWeights ) +{ + word F1 = t; + word F0 = ~F1; + word Func; + int i, Cost = 0; + printf( "Trying: " ); + Extra_PrintHex( stdout, (unsigned *)&t, 6 ); printf( "\n" ); +// Abc_Show6VarFunc( F0, F1 ); + for ( i = 0; F0 && F1; i++ ) + { + printf( "*** ITER %2d ", i ); + Func = Bdc_SpfdFindBest( vDivs, vWeights, F0, F1, &Cost ); + F0 &= ~Func; + F1 &= ~Func; +// Abc_Show6VarFunc( F0, F1 ); + } + Cost += (i-1); + printf( "Produce solution with cost %2d (with adj cost %4d).\n", Cost, Bdc_SpfdAdjCost(t) ); + return Cost; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdDecomposeTest44() +{ +// word t = 0x5052585a0002080a; + + word t = 0x9ef7a8d9c7193a0f; +// word t = 0x6BFDA276C7193A0F; +// word t = 0xA3756AFE0B1DF60B; + +// word t = 0xFEF7AEBFCE80AA0F; +// word t = 0x9EF7FDBFC77F6F0F; +// word t = 0xDEF7FDFF377F6FFF; + +// word t = 0x345D02736DB390A5; // xor with var 0 + +// word t = 0x3EFDA2736D139A0F; // best solution after changes + + Vec_Int_t * vWeights; + Vec_Wrd_t * vDivs; + word c0, c1, s, tt, tbest; + int i, j, Cost, CostBest = 100000; + int clk = clock(); + + return; + +// printf( "%d\n", RAND_MAX ); + + vDivs = Bdc_SpfdDecomposeTest__( &vWeights ); +// vDivs = Bdc_SpfdReadFiles5( &vWeights ); + +// Abc_Show6VarFunc( ~t, t ); + + // try function + tt = t; + Cost = Bdc_SpfdDecomposeTestOne( tt, vDivs, vWeights ); + if ( CostBest > Cost ) + { + CostBest = Cost; + tbest = tt; + } + printf( "\n" ); + + // try complemented output + for ( i = 0; i < 6; i++ ) + { + tt = t ^ Truths[i]; + Cost = Bdc_SpfdDecomposeTestOne( tt, vDivs, vWeights ); + if ( CostBest > Cost ) + { + CostBest = Cost; + tbest = tt; + } + } + printf( "\n" ); + + // try complemented input + for ( i = 0; i < 6; i++ ) + for ( j = 0; j < 6; j++ ) + { + if ( i == j ) + continue; + c0 = Bdc_Cof6( t, i, 0 ); + c1 = Bdc_Cof6( t, i, 1 ); + s = Truths[i] ^ Truths[j]; + tt = (~s & c0) | (s & c1); + + Cost = Bdc_SpfdDecomposeTestOne( tt, vDivs, vWeights ); + if ( CostBest > Cost ) + { + CostBest = Cost; + tbest = tt; + } + } + +/* + for ( i = 0; i < 6; i++ ) + for ( j = 0; j < 6; j++ ) + { + if ( i == j ) + continue; + c0 = Bdc_Cof6( t, i, 0 ); + c1 = Bdc_Cof6( t, i, 1 ); + s = Truths[i] ^ Truths[j]; + tt = (~s & c0) | (s & c1); + + for ( k = 0; k < 6; k++ ) + for ( n = 0; n < 6; n++ ) + { + if ( k == n ) + continue; + c0 = Bdc_Cof6( tt, k, 0 ); + c1 = Bdc_Cof6( tt, k, 1 ); + s = Truths[k] ^ Truths[n]; + ttt= (~s & c0) | (s & c1); + + Cost = Bdc_SpfdDecomposeTestOne( ttt, vDivs, vWeights ); + if ( CostBest > Cost ) + { + CostBest = Cost; + tbest = ttt; + } + } + } +*/ + + printf( "Best solution found with cost %d. ", CostBest ); + Extra_PrintHex( stdout, (unsigned *)&tbest, 6 ); //printf( "\n" ); + Abc_PrintTime( 1, " Time", clock() - clk ); + + Vec_WrdFree( vDivs ); + Vec_IntFree( vWeights ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdDecomposeTest3() +{ + int nSizeM = (1 << 26); + int nSizeK = (1 << 3); + Vec_Wrd_t * v1M; + Vec_Wrd_t * v1K; + int i, k, Counter, clk; +// int EntryM, EntryK; + Aig_ManRandom64( 1 ); + + v1M = Vec_WrdAlloc( nSizeM ); + for ( i = 0; i < nSizeM; i++ ) + Vec_WrdPush( v1M, Aig_ManRandom64(0) ); + + v1K = Vec_WrdAlloc( nSizeK ); + for ( i = 0; i < nSizeK; i++ ) + Vec_WrdPush( v1K, Aig_ManRandom64(0) ); + + clk = clock(); + Counter = 0; + for ( i = 0; i < nSizeM; i++ ) + for ( k = 0; k < nSizeK; k++ ) + Counter += ((v1M->pArray[i] & v1K->pArray[k]) == v1K->pArray[k]); +// Vec_WrdForEachEntry( v1M, EntryM, i ) +// Vec_WrdForEachEntry( v1K, EntryK, k ) +// Counter += ((EntryM & EntryK) == EntryK); + + printf( "Total = %8d. ", Counter ); + Abc_PrintTime( 1, "Time", clock() - clk ); + + clk = clock(); + Counter = 0; + for ( k = 0; k < nSizeK; k++ ) + for ( i = 0; i < nSizeM; i++ ) + Counter += ((v1M->pArray[i] & v1K->pArray[k]) == v1K->pArray[k]); + printf( "Total = %8d. ", Counter ); + Abc_PrintTime( 1, "Time", clock() - clk ); + +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdDecomposeTest8() +{ +// word t = 0x9ef7a8d9c7193a0f; +// word t = 0x9EF7FDBFC77F6F0F; + word t = 0x513B57150819050F; + + Vec_Int_t * vWeights; + Vec_Wrd_t * vDivs; + word Func, FuncBest; + int Cost, CostBest = ABC_INFINITY; + int i, clk = clock(); + +// return; + + vDivs = Bdc_SpfdReadFiles5( &vWeights ); + + printf( "Best init = %4d. ", Bdc_SpfdAdjCost(t) ); + Extra_PrintHex( stdout, (unsigned *)&t, 6 ); //printf( "\n" ); + Abc_PrintTime( 1, " Time", clock() - clk ); + + Vec_WrdForEachEntry( vDivs, Func, i ) + { + Cost = Bdc_SpfdAdjCost( t ^ Func ); + if ( CostBest > Cost ) + { + CostBest = Cost; + FuncBest = Func; + } + } + + printf( "Best cost = %4d. ", CostBest ); + Extra_PrintHex( stdout, (unsigned *)&FuncBest, 6 ); //printf( "\n" ); + Abc_PrintTime( 1, " Time", clock() - clk ); + +Abc_Show6VarFunc( 0, t ); +Abc_Show6VarFunc( 0, FuncBest ); +Abc_Show6VarFunc( 0, (FuncBest ^ t) ); + + FuncBest ^= t; + Extra_PrintHex( stdout, (unsigned *)&FuncBest, 6 ); printf( "\n" ); + +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_SpfdDecomposeTest() +{ + int nSizeM = (1 << 26); // big array size + int nSizeK = (1 << 3); // small array size + Vec_Wrd_t * v1M, * v1K; + int EntryM, EntryK; + int i, k, Counter, clk; + + Aig_ManRandom64( 1 ); + + v1M = Vec_WrdAlloc( nSizeM ); + for ( i = 0; i < nSizeM; i++ ) + Vec_WrdPush( v1M, Aig_ManRandom64(0) ); + + v1K = Vec_WrdAlloc( nSizeK ); + for ( i = 0; i < nSizeK; i++ ) + Vec_WrdPush( v1K, Aig_ManRandom64(0) ); + + clk = clock(); + Counter = 0; +// for ( i = 0; i < nSizeM; i++ ) +// for ( k = 0; k < nSizeK; k++ ) +// Counter += ((v1M->pArray[i] & v1K->pArray[k]) == v1K->pArray[k]); + Vec_WrdForEachEntry( v1M, EntryM, i ) + Vec_WrdForEachEntry( v1K, EntryK, k ) + Counter += ((EntryM & EntryK) == EntryK); + printf( "Total = %8d. ", Counter ); + Abc_PrintTime( 1, "Time", clock() - clk ); + + clk = clock(); + Counter = 0; +// for ( k = 0; k < nSizeK; k++ ) +// for ( i = 0; i < nSizeM; i++ ) +// Counter += ((v1M->pArray[i] & v1K->pArray[k]) == v1K->pArray[k]); + Vec_WrdForEachEntry( v1K, EntryK, k ) + Vec_WrdForEachEntry( v1M, EntryM, i ) + Counter += ((EntryM & EntryK) == EntryK); + printf( "Total = %8d. ", Counter ); + Abc_PrintTime( 1, "Time", clock() - clk ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/bool/bdc/bdcTable.c b/src/bool/bdc/bdcTable.c new file mode 100644 index 00000000..69f35d88 --- /dev/null +++ b/src/bool/bdc/bdcTable.c @@ -0,0 +1,134 @@ +/**CFile**************************************************************** + + FileName [bdcTable.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Truth-table-based bi-decomposition engine.] + + Synopsis [Hash table for intermediate nodes.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 30, 2007.] + + Revision [$Id: bdcTable.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bdcInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Checks containment of the function in the ISF.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bdc_TableCheckContainment( Bdc_Man_t * p, Bdc_Isf_t * pIsf, unsigned * puTruth ) +{ + return Kit_TruthIsImply( pIsf->puOn, puTruth, p->nVars ) && + Kit_TruthIsDisjoint( puTruth, pIsf->puOff, p->nVars ); +} + +/**Function************************************************************* + + Synopsis [Adds the new entry to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bdc_Fun_t * Bdc_TableLookup( Bdc_Man_t * p, Bdc_Isf_t * pIsf ) +{ + int fDisableCache = 0; + Bdc_Fun_t * pFunc; + if ( fDisableCache && Kit_WordCountOnes(pIsf->uSupp) > 1 ) + return NULL; + if ( pIsf->uSupp == 0 ) + { + assert( p->pTable[pIsf->uSupp] == p->pNodes ); + if ( Kit_TruthIsConst1( pIsf->puOn, p->nVars ) ) + return p->pNodes; + assert( Kit_TruthIsConst1( pIsf->puOff, p->nVars ) ); + return Bdc_Not(p->pNodes); + } + for ( pFunc = p->pTable[pIsf->uSupp]; pFunc; pFunc = pFunc->pNext ) + if ( Bdc_TableCheckContainment( p, pIsf, pFunc->puFunc ) ) + return pFunc; + Bdc_IsfNot( pIsf ); + for ( pFunc = p->pTable[pIsf->uSupp]; pFunc; pFunc = pFunc->pNext ) + if ( Bdc_TableCheckContainment( p, pIsf, pFunc->puFunc ) ) + { + Bdc_IsfNot( pIsf ); + return Bdc_Not(pFunc); + } + Bdc_IsfNot( pIsf ); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Adds the new entry to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_TableAdd( Bdc_Man_t * p, Bdc_Fun_t * pFunc ) +{ + if ( p->pTable[pFunc->uSupp] == NULL ) + Vec_IntPush( p->vSpots, pFunc->uSupp ); + pFunc->pNext = p->pTable[pFunc->uSupp]; + p->pTable[pFunc->uSupp] = pFunc; +} + +/**Function************************************************************* + + Synopsis [Adds the new entry to the hash table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bdc_TableClear( Bdc_Man_t * p ) +{ + int Spot, i; + Vec_IntForEachEntry( p->vSpots, Spot, i ) + p->pTable[Spot] = NULL; + Vec_IntClear( p->vSpots ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/bool/bdc/bdc_.c b/src/bool/bdc/bdc_.c new file mode 100644 index 00000000..b29d4f5e --- /dev/null +++ b/src/bool/bdc/bdc_.c @@ -0,0 +1,54 @@ +/**CFile**************************************************************** + + FileName [bdc_.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Truth-table-based bi-decomposition engine.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - January 30, 2007.] + + Revision [$Id: bdc_.c,v 1.00 2007/01/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bdcInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/bool/bdc/module.make b/src/bool/bdc/module.make new file mode 100644 index 00000000..0bd5084e --- /dev/null +++ b/src/bool/bdc/module.make @@ -0,0 +1,5 @@ +SRC += src/bool/bdc/bdcCore.c \ + src/bool/bdc/bdcDec.c \ + src/bool/bdc/bdcSpfd.c \ + src/bool/bdc/bdcTable.c + |