void Gia_ManMarkSeqGiaWithBoxes( Gia_Man_t * p, int fSeq ) { // CI order: real PIs + flop outputs + box outputs // CO order: box inputs + real POs + flop inputs Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; Vec_Int_t * vRoots; Gia_Obj_t * pObj; int nRealCis = Tim_ManPiNum(pManTime); int nRealCos = Tim_ManPoNum(pManTime); int i, nRegs = fSeq ? Gia_ManRegBoxNum(p) : 0; assert( Gia_ManRegNum(p) == 0 ); assert( Gia_ManBoxNum(p) > 0 ); // mark the terminals Gia_ManIncrementTravId( p ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); for ( i = 0; i < nRealCis - nRegs; i++ ) Gia_ObjSetTravIdCurrent( p, Gia_ManPi(p, i) ); // collect flops reachable from the POs vRoots = Vec_IntAlloc( Gia_ManRegBoxNum(p) ); for ( i = Gia_ManPoNum(p) - nRealCos; i < Gia_ManPoNum(p) - nRegs; i++ ) { Gia_ObjSetTravIdCurrent( p, Gia_ManPo(p, i) ); Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(Gia_ManPo(p, i)), vRoots ); } // collect flops reachable from roots if ( fSeq ) { Gia_ManForEachObjVec( vRoots, p, pObj, i ) { assert( Gia_ObjIsCo(pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); Gia_ManMarkSeqGiaWithBoxes_rec( p, Gia_ObjFanin0(pObj), vRoots ); } //printf( "Explored %d flops\n", Vec_IntSize(vRoots) ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Resimulates the counter-example.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManVerifyCex( Gia_Man_t * pAig, Abc_Cex_t * p, int fDualOut ) { Gia_Obj_t * pObj, * pObjRi, * pObjRo; int RetValue, i, k, iBit = 0; Gia_ManCleanMark0(pAig); Gia_ManForEachRo( pAig, pObj, i ) pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); for ( i = 0; i <= p->iFrame; i++ ) { Gia_ManForEachPi( pAig, pObj, k ) pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); Gia_ManForEachAnd( pAig, pObj, k ) pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); Gia_ManForEachCo( pAig, pObj, k ) pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); if ( i == p->iFrame ) break; Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) { pObjRo->fMark0 = pObjRi->fMark0; } } assert( iBit == p->nBits ); if ( fDualOut ) RetValue = Gia_ManPo(pAig, 2*p->iPo)->fMark0 ^ Gia_ManPo(pAig, 2*p->iPo+1)->fMark0; else RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; Gia_ManCleanMark0(pAig); return RetValue; }
/**Function************************************************************* Synopsis [Performs targe enlargement of the given size.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Bmc_CexTargetEnlarge( Gia_Man_t * p, int nFrames ) { Gia_Man_t * pNew, * pOne; Gia_Obj_t * pObj, * pObjRo; int i, k; pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManHashAlloc( pNew ); Gia_ManConst0(p)->Value = 0; for ( k = 0; k < nFrames; k++ ) Gia_ManForEachPi( p, pObj, i ) Gia_ManAppendCi( pNew ); Gia_ManForEachRo( p, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); for ( k = 0; k < nFrames; k++ ) { Gia_ManForEachPi( p, pObj, i ) pObj->Value = Gia_ManCiLit( pNew, (nFrames - 1 - k) * Gia_ManPiNum(p) + i ); Gia_ManForEachAnd( p, pObj, i ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachRi( p, pObj, i ) pObj->Value = Gia_ObjFanin0Copy(pObj); Gia_ManForEachRiRo( p, pObj, pObjRo, i ) pObjRo->Value = pObj->Value; } pObj = Gia_ManPo( p, 0 ); pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); Gia_ManHashStop( pNew ); pNew = Gia_ManCleanup( pOne = pNew ); Gia_ManStop( pOne ); return pNew; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Cec_ManHandleSpecialCases( Gia_Man_t * p, Cec_ParCec_t * pPars ) { Gia_Obj_t * pObj1, * pObj2; Gia_Obj_t * pDri1, * pDri2; int i; abctime clk = Abc_Clock(); Gia_ManSetPhase( p ); Gia_ManForEachPo( p, pObj1, i ) { pObj2 = Gia_ManPo( p, ++i ); // check if they different on all-0 pattern // (for example, when they have the same driver but complemented) if ( Gia_ObjPhase(pObj1) != Gia_ObjPhase(pObj2) ) { Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d trivially differs (different phase). ", i/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); pPars->iOutFail = i/2; Cec_ManTransformPattern( p, i/2, NULL ); return 0; } // get the drivers pDri1 = Gia_ObjFanin0(pObj1); pDri2 = Gia_ObjFanin0(pObj2); // drivers are different PIs if ( Gia_ObjIsPi(p, pDri1) && Gia_ObjIsPi(p, pDri2) && pDri1 != pDri2 ) { Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d trivially differs (different PIs). ", i/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); pPars->iOutFail = i/2; Cec_ManTransformPattern( p, i/2, NULL ); // if their compl attributes are the same - one should be complemented assert( Gia_ObjFaninC0(pObj1) == Gia_ObjFaninC0(pObj2) ); Abc_InfoSetBit( p->pCexComb->pData, Gia_ObjCioId(pDri1) ); return 0; } // one of the drivers is a PI; another is a constant 0 if ( (Gia_ObjIsPi(p, pDri1) && Gia_ObjIsConst0(pDri2)) || (Gia_ObjIsPi(p, pDri2) && Gia_ObjIsConst0(pDri1)) ) { Abc_Print( 1, "Networks are NOT EQUIVALENT. Output %d trivially differs (PI vs. constant). ", i/2 ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); pPars->iOutFail = i/2; Cec_ManTransformPattern( p, i/2, NULL ); // the compl attributes are the same - the PI should be complemented assert( Gia_ObjFaninC0(pObj1) == Gia_ObjFaninC0(pObj2) ); if ( Gia_ObjIsPi(p, pDri1) ) Abc_InfoSetBit( p->pCexComb->pData, Gia_ObjCioId(pDri1) ); else Abc_InfoSetBit( p->pCexComb->pData, Gia_ObjCioId(pDri2) ); return 0; } }
/**Function************************************************************* Synopsis [Compute the patch function.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Bmc_EcoPatch( Gia_Man_t * p, int nIns, int nOuts ) { int i, Lit, RetValue, Root; Gia_Obj_t * pObj; Vec_Int_t * vVars; // generate CNF and solver Cnf_Dat_t * pCnf = Cnf_DeriveGiaRemapped( p ); sat_solver * pSat = sat_solver_new(); sat_solver_setnvars( pSat, pCnf->nVars ); // add timeframe clauses for ( i = 0; i < pCnf->nClauses; i++ ) if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) assert( 0 ); // add equality constraints assert( Gia_ManPoNum(p) == nOuts + 1 + nIns ); Gia_ManForEachPo( p, pObj, i ) { if ( i == nOuts ) break; Lit = Abc_Var2Lit( pCnf->pVarNums[Gia_ObjId(p, pObj)], 1 ); // neg lit RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); assert( RetValue ); } // add inequality constraint pObj = Gia_ManPo( p, nOuts ); Lit = Abc_Var2Lit( pCnf->pVarNums[Gia_ObjId(p, pObj)], 0 ); // pos lit RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); assert( RetValue ); // simplify the SAT solver RetValue = sat_solver_simplify( pSat ); assert( RetValue ); // collect input variables vVars = Vec_IntAlloc( nIns ); Gia_ManForEachPo( p, pObj, i ) if ( i >= nOuts + 1 ) Vec_IntPush( vVars, pCnf->pVarNums[Gia_ObjId(p, pObj)] ); assert( Vec_IntSize(vVars) == nIns ); // derive the root variable pObj = Gia_ManPi( p, Gia_ManPiNum(p) - 1 ); Root = pCnf->pVarNums[Gia_ObjId(p, pObj)]; // solve the problem RetValue = Bmc_EcoSolve( pSat, Root, vVars ); Vec_IntFree( vVars ); return RetValue; }
/**Function************************************************************* Synopsis [Resimulates the counter-example.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManFindFailedPoCex( Gia_Man_t * pAig, Abc_Cex_t * p, int nOutputs ) { Gia_Obj_t * pObj, * pObjRi, * pObjRo; int RetValue, i, k, iBit = 0; assert( Gia_ManPiNum(pAig) == p->nPis ); Gia_ManCleanMark0(pAig); // Gia_ManForEachRo( pAig, pObj, i ) // pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); iBit = p->nRegs; for ( i = 0; i <= p->iFrame; i++ ) { Gia_ManForEachPi( pAig, pObj, k ) pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); Gia_ManForEachAnd( pAig, pObj, k ) pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); Gia_ManForEachCo( pAig, pObj, k ) pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) pObjRo->fMark0 = pObjRi->fMark0; } assert( iBit == p->nBits ); // figure out the number of failed output RetValue = -1; // for ( i = Gia_ManPoNum(pAig) - 1; i >= nOutputs; i-- ) for ( i = nOutputs; i < Gia_ManPoNum(pAig); i++ ) { if ( Gia_ManPo(pAig, i)->fMark0 ) { RetValue = i; break; } } Gia_ManCleanMark0(pAig); return RetValue; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Computes miter for ECO with given root node and fanins.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Bmc_EcoMiter( Gia_Man_t * pGold, Gia_Man_t * pOld, Vec_Int_t * vFans ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pRoot = Gia_ObjFanin0( Gia_ManPo(pOld, Gia_ManPoNum(pOld)-1) ); // fanin of the last PO Gia_Obj_t * pObj; int i, NewPi, Miter; assert( Gia_ManCiNum(pGold) == Gia_ManCiNum(pOld) ); assert( Gia_ManCoNum(pGold) == Gia_ManCoNum(pOld) - 1 ); assert( Gia_ObjIsAnd(pRoot) ); // create the miter pNew = Gia_ManStart( 3 * Gia_ManObjNum(pGold) ); pNew->pName = Abc_UtilStrsav( pGold->pName ); Gia_ManHashAlloc( pNew ); // copy gold Gia_ManConst0(pGold)->Value = 0; Gia_ManForEachCi( pGold, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); NewPi = Gia_ManAppendCi( pNew ); Gia_ManForEachAnd( pGold, pObj, i ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pGold, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); // create onset Gia_ManConst0(pOld)->Value = 0; Gia_ManForEachCi( pOld, pObj, i ) pObj->Value = Gia_ManCi(pGold, i)->Value; Gia_ManForEachAnd( pOld, pObj, i ) if ( pObj == pRoot ) pObj->Value = NewPi; else pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pOld, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); Gia_ManForEachCo( pGold, pObj, i ) Gia_ManAppendCo( pNew, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) ); // create offset Gia_ManForEachAnd( pOld, pObj, i ) if ( pObj == pRoot ) pObj->Value = Abc_LitNot(NewPi); else pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( pOld, pObj, i ) pObj->Value = Gia_ObjFanin0Copy( pObj ); Miter = 0; Gia_ManForEachCo( pGold, pObj, i ) Miter = Gia_ManHashOr( pNew, Miter, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) ); Gia_ManAppendCo( pNew, Miter ); // add outputs for the nodes Gia_ManForEachObjVec( vFans, pOld, pObj, i ) Gia_ManAppendCo( pNew, pObj->Value ); // cleanup pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); assert( Gia_ManPiNum(pNew) == Gia_ManCiNum(pGold) + 1 ); assert( Gia_ManPoNum(pNew) == Gia_ManCoNum(pGold) + 1 + Vec_IntSize(vFans) ); return pNew; }
Vec_Int_t * Gia_ManOrderWithBoxes( Gia_Man_t * p ) { Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime; Vec_Int_t * vNodes; Gia_Obj_t * pObj; int i, k, curCi, curCo; assert( pManTime != NULL ); assert( Gia_ManIsNormalized( p ) ); // start trav IDs Gia_ManIncrementTravId( p ); // start the array vNodes = Vec_IntAlloc( Gia_ManObjNum(p) ); // include constant Vec_IntPush( vNodes, 0 ); Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) ); // include primary inputs for ( i = 0; i < Tim_ManPiNum(pManTime); i++ ) { pObj = Gia_ManPi( p, i ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); assert( Gia_ObjId(p, pObj) == i+1 ); } // for each box, include box nodes curCi = Tim_ManPiNum(pManTime); curCo = 0; for ( i = 0; i < Tim_ManBoxNum(pManTime); i++ ) { // add internal nodes for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ ) { pObj = Gia_ManPo( p, curCo + k ); if ( Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ) ) { int iCiNum = p->iData2; int iBoxNum = Tim_ManBoxFindFromCiNum( pManTime, iCiNum ); printf( "Boxes are not in a topological order. The command has to terminate.\n" ); printf( "The following information may help debugging (numbers are 0-based):\n" ); printf( "Input %d of BoxA %d (1stCI = %d; 1stCO = %d) has TFI with CI %d,\n", k, i, Tim_ManBoxOutputFirst(pManTime, i), Tim_ManBoxInputFirst(pManTime, i), iCiNum ); printf( "which corresponds to output %d of BoxB %d (1stCI = %d; 1stCO = %d).\n", iCiNum - Tim_ManBoxOutputFirst(pManTime, iBoxNum), iBoxNum, Tim_ManBoxOutputFirst(pManTime, iBoxNum), Tim_ManBoxInputFirst(pManTime, iBoxNum) ); printf( "In a correct topological order, BoxB should preceed BoxA.\n" ); Vec_IntFree( vNodes ); p->iData2 = 0; return NULL; } } // add POs corresponding to box inputs for ( k = 0; k < Tim_ManBoxInputNum(pManTime, i); k++ ) { pObj = Gia_ManPo( p, curCo + k ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); } curCo += Tim_ManBoxInputNum(pManTime, i); // add PIs corresponding to box outputs for ( k = 0; k < Tim_ManBoxOutputNum(pManTime, i); k++ ) { pObj = Gia_ManPi( p, curCi + k ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); Gia_ObjSetTravIdCurrent( p, pObj ); } curCi += Tim_ManBoxOutputNum(pManTime, i); } // add remaining nodes for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ ) { pObj = Gia_ManPo( p, i ); Gia_ManOrderWithBoxes_rec( p, Gia_ObjFanin0(pObj), vNodes ); } // add POs for ( i = Tim_ManCoNum(pManTime) - Tim_ManPoNum(pManTime); i < Tim_ManCoNum(pManTime); i++ ) { pObj = Gia_ManPo( p, i ); Vec_IntPush( vNodes, Gia_ObjId(p, pObj) ); } curCo += Tim_ManPoNum(pManTime); // verify counts assert( curCi == Gia_ManPiNum(p) ); assert( curCo == Gia_ManPoNum(p) ); assert( Vec_IntSize(vNodes) == Gia_ManObjNum(p) ); return vNodes; }