/**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, VarBest, Cost, VarCostBest = 0; for ( v = 0; v < p->nVars; v++ ) { Kit_TruthExistNew( p->puTemp1, pIsf->puOff, p->nVars, v ); // 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 ) 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->Var = VarBest; // assert( pL->Q != b0 ); // assert( pL->R != b0 ); // assert( Cudd_bddIteConstant( dd, pL->Q, pL->R, b0 ) == b0 ); // 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 [Implements support-reducing decomposition.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ If_Obj_t * Lpk_MapSuppRedDec_rec( Lpk_Man_t * p, unsigned * pTruth, int nVars, If_Obj_t ** ppLeaves ) { Kit_DsdNtk_t * pNtkDec, * pNtkComp, * ppNtks[2], * pTemp; If_Obj_t * pObjNew; unsigned * pCof0 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 0 ); unsigned * pCof1 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 1 ); unsigned * pDec0 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 2 ); unsigned * pDec1 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 3 ); unsigned * pDec = (unsigned *)Vec_PtrEntry( p->vTtNodes, 4 ); unsigned * pCo00 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 5 ); unsigned * pCo01 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 6 ); unsigned * pCo10 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 7 ); unsigned * pCo11 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 8 ); unsigned * pCo0 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 9 ); unsigned * pCo1 = (unsigned *)Vec_PtrEntry( p->vTtNodes, 10 ); unsigned * pCo = (unsigned *)Vec_PtrEntry( p->vTtNodes, 11 ); int TrueMint0, TrueMint1, FalseMint0, FalseMint1; int uSubsets, uSubset0, uSubset1, iVar, iVarReused, i; // determine if supp-red decomposition exists uSubsets = Lpk_MapSuppRedDecSelect( p, pTruth, nVars, &iVar, &iVarReused ); if ( uSubsets == 0 ) return NULL; p->nCalledSRed++; // get the cofactors Kit_TruthCofactor0New( pCof0, pTruth, nVars, iVar ); Kit_TruthCofactor1New( pCof1, pTruth, nVars, iVar ); // get the bound sets uSubset0 = uSubsets & 0xFFFF; uSubset1 = uSubsets >> 16; // compute the decomposed functions ppNtks[0] = Kit_DsdDecompose( pCof0, nVars ); ppNtks[1] = Kit_DsdDecompose( pCof1, nVars ); ppNtks[0] = Kit_DsdExpand( pTemp = ppNtks[0] ); Kit_DsdNtkFree( pTemp ); ppNtks[1] = Kit_DsdExpand( pTemp = ppNtks[1] ); Kit_DsdNtkFree( pTemp ); Kit_DsdTruthPartial( p->pDsdMan, ppNtks[0], pDec0, uSubset0 ); Kit_DsdTruthPartial( p->pDsdMan, ppNtks[1], pDec1, uSubset1 ); // Kit_DsdTruthPartialTwo( p->pDsdMan, ppNtks[0], uSubset0, iVarReused, pCo0, pDec0 ); // Kit_DsdTruthPartialTwo( p->pDsdMan, ppNtks[1], uSubset1, iVarReused, pCo1, pDec1 ); Kit_DsdNtkFree( ppNtks[0] ); Kit_DsdNtkFree( ppNtks[1] ); //Kit_DsdPrintFromTruth( pDec0, nVars ); //Kit_DsdPrintFromTruth( pDec1, nVars ); // get the decomposed function Kit_TruthMuxVar( pDec, pDec0, pDec1, nVars, iVar ); // find any true assignments of the decomposed functions TrueMint0 = Kit_TruthFindFirstBit( pDec0, nVars ); TrueMint1 = Kit_TruthFindFirstBit( pDec1, nVars ); assert( TrueMint0 >= 0 && TrueMint1 >= 0 ); // find any false assignments of the decomposed functions FalseMint0 = Kit_TruthFindFirstZero( pDec0, nVars ); FalseMint1 = Kit_TruthFindFirstZero( pDec1, nVars ); assert( FalseMint0 >= 0 && FalseMint1 >= 0 ); // cofactor the cofactors according to these minterms Kit_TruthCopy( pCo00, pCof0, nVars ); Kit_TruthCopy( pCo01, pCof0, nVars ); for ( i = 0; i < nVars; i++ ) if ( uSubset0 & (1 << i) ) { if ( FalseMint0 & (1 << i) ) Kit_TruthCofactor1( pCo00, nVars, i ); else Kit_TruthCofactor0( pCo00, nVars, i ); if ( TrueMint0 & (1 << i) ) Kit_TruthCofactor1( pCo01, nVars, i ); else Kit_TruthCofactor0( pCo01, nVars, i ); } Kit_TruthCopy( pCo10, pCof1, nVars ); Kit_TruthCopy( pCo11, pCof1, nVars ); for ( i = 0; i < nVars; i++ ) if ( uSubset1 & (1 << i) ) { if ( FalseMint1 & (1 << i) ) Kit_TruthCofactor1( pCo10, nVars, i ); else Kit_TruthCofactor0( pCo10, nVars, i ); if ( TrueMint1 & (1 << i) ) Kit_TruthCofactor1( pCo11, nVars, i ); else Kit_TruthCofactor0( pCo11, nVars, i ); } // derive the functions by composing them with the new variable (iVarReused) Kit_TruthMuxVar( pCo0, pCo00, pCo01, nVars, iVarReused ); Kit_TruthMuxVar( pCo1, pCo10, pCo11, nVars, iVarReused ); //Kit_DsdPrintFromTruth( pCo0, nVars ); //Kit_DsdPrintFromTruth( pCo1, nVars ); // derive the composition function Kit_TruthMuxVar( pCo , pCo0 , pCo1 , nVars, iVar ); // process the decomposed function pNtkDec = Kit_DsdDecompose( pDec, nVars ); pNtkComp = Kit_DsdDecompose( pCo, nVars ); //Kit_DsdPrint( stdout, pNtkDec ); //Kit_DsdPrint( stdout, pNtkComp ); //printf( "cofactored variable %c\n", 'a' + iVar ); //printf( "reused variable %c\n", 'a' + iVarReused ); ppLeaves[iVarReused] = Lpk_MapTree_rec( p, pNtkDec, ppLeaves, pNtkDec->Root, NULL ); pObjNew = Lpk_MapTree_rec( p, pNtkComp, ppLeaves, pNtkComp->Root, NULL ); Kit_DsdNtkFree( pNtkDec ); Kit_DsdNtkFree( pNtkComp ); return pObjNew; }
/**Function************************************************************* Synopsis [Starts the record for the given network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkRecStart( Abc_Ntk_t * pNtk, int nVars, int nCuts ) { Abc_ManRec_t * p; Abc_Obj_t * pObj, ** ppSpot; char Buffer[10]; unsigned * pTruth; int i, RetValue; int clkTotal = clock(), clk; assert( s_pMan == NULL ); if ( pNtk == NULL ) { assert( nVars > 2 && nVars <= 16 ); pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); pNtk->pName = Extra_UtilStrsav( "record" ); } else { if ( Abc_NtkGetChoiceNum(pNtk) > 0 ) { printf( "The starting record should be a network without choice nodes.\n" ); return; } if ( Abc_NtkPiNum(pNtk) > 16 ) { printf( "The starting record should be a network with no more than %d primary inputs.\n", 16 ); return; } if ( Abc_NtkPiNum(pNtk) > nVars ) printf( "The starting record has %d inputs (warning only).\n", Abc_NtkPiNum(pNtk) ); pNtk = Abc_NtkDup( pNtk ); } // create the primary inputs for ( i = Abc_NtkPiNum(pNtk); i < nVars; i++ ) { pObj = Abc_NtkCreatePi( pNtk ); Buffer[0] = 'a' + i; Buffer[1] = 0; Abc_ObjAssignName( pObj, Buffer, NULL ); } Abc_NtkCleanCopy( pNtk ); Abc_NtkCleanEquiv( pNtk ); // start the manager p = ABC_ALLOC( Abc_ManRec_t, 1 ); memset( p, 0, sizeof(Abc_ManRec_t) ); p->pNtk = pNtk; p->nVars = Abc_NtkPiNum(pNtk); p->nWords = Kit_TruthWordNum( p->nVars ); p->nCuts = nCuts; p->nVarsInit = nVars; // create elementary truth tables p->vTtElems = Vec_PtrAlloc( 0 ); assert( p->vTtElems->pArray == NULL ); p->vTtElems->nSize = p->nVars; p->vTtElems->nCap = p->nVars; p->vTtElems->pArray = (void *)Extra_TruthElementary( p->nVars ); // allocate room for node truth tables if ( Abc_NtkObjNum(pNtk) > (1<<14) ) p->vTtNodes = Vec_PtrAllocSimInfo( 2 * Abc_NtkObjNum(pNtk), p->nWords ); else p->vTtNodes = Vec_PtrAllocSimInfo( 1<<14, p->nWords ); // create hash table p->nBins = 50011; p->pBins = ABC_ALLOC( Abc_Obj_t *, p->nBins ); memset( p->pBins, 0, sizeof(Abc_Obj_t *) * p->nBins ); // set elementary tables Kit_TruthFill( Vec_PtrEntry(p->vTtNodes, 0), p->nVars ); Abc_NtkForEachPi( pNtk, pObj, i ) Kit_TruthCopy( Vec_PtrEntry(p->vTtNodes, pObj->Id), Vec_PtrEntry(p->vTtElems, i), p->nVars ); // compute the tables clk = clock(); Abc_AigForEachAnd( pNtk, pObj, i ) { RetValue = Abc_NtkRecComputeTruth( pObj, p->vTtNodes, p->nVars ); assert( RetValue ); }
/**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 uSuppRem; int v, nLeftVars = 1, nRightVars = 1; // clean the var sets Bdc_IsfClean( pIsfL ); Bdc_IsfClean( pIsfR ); // 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_TruthExistNew( p->puTemp1, pIsf->puOff, p->nVars, pIsfL->Var ); Kit_TruthExistNew( p->puTemp2, pIsf->puOff, p->nVars, pIsfR->Var ); // go through the remaining variables uSuppRem = pIsf->uSupp & ~pIsfL->uSupp & ~pIsfR->uSupp; assert( Kit_WordCountOnes(uSuppRem) > 0 ); for ( v = 0; v < p->nVars; v++ ) { if ( (uSuppRem & (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->uSupp |= (1 << v); nLeftVars++; } // 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->uSupp |= (1 << v); nRightVars++; } } 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->uSupp |= (1 << v); nRightVars++; } // 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->uSupp |= (1 << v); nLeftVars++; } } } // 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->uSupp ); Kit_TruthCopy( pIsfL->puOff, p->puTemp2, 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->uSupp ); Kit_TruthCopy( pIsfR->puOff, p->puTemp1, 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) ); return Bdc_DecomposeGetCost( p, nLeftVars, nRightVars ); }