| /**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; |
| abctime clk = 0; // Suppress "might be used uninitialized" |
| if ( p->pPars->fVerbose ) |
| clk = Abc_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 += Abc_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; |
| abctime clk = 0; // Suppress "might be used uninitialized" |
| if ( p->pPars->fVerbose ) |
| clk = Abc_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 += Abc_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; |
| abctime clk = 0; // Suppress "might be used uninitialized" |
| if ( p->pPars->fVerbose ) |
| clk = Abc_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 += Abc_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; |
| abctime 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 = Abc_Clock(); |
| pFunc = Bdc_TableLookup( p, pIsf ); |
| if ( p->pPars->fVerbose ) |
| p->timeCache += Abc_Clock() - clk; |
| if ( pFunc ) |
| return pFunc; |
| // decide on the decomposition type |
| if ( p->pPars->fVerbose ) |
| clk = Abc_Clock(); |
| Type = Bdc_DecomposeStep( p, pIsf, pIsfL, pIsfR ); |
| if ( p->pPars->fVerbose ) |
| p->timeCheck += Abc_Clock() - clk; |
| if ( Type == BDC_TYPE_MUX ) |
| { |
| if ( p->pPars->fVerbose ) |
| clk = Abc_Clock(); |
| iVar = Bdc_DecomposeStepMux( p, pIsf, pIsfL, pIsfR ); |
| if ( p->pPars->fVerbose ) |
| p->timeMuxes += Abc_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 |
| |