ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Detects multi-input AND gate rooted at this node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManFindImplications_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vImplics ) { if ( Aig_IsComplement(pObj) || Aig_ObjIsCi(pObj) ) { Vec_PtrPushUnique( vImplics, pObj ); return; } Aig_ManFindImplications_rec( Aig_ObjChild0(pObj), vImplics ); Aig_ManFindImplications_rec( Aig_ObjChild1(pObj), vImplics ); }
/**Function************************************************************* Synopsis [Duplicates AIG in the DFS order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManFromAigSimple( Aig_Man_t * p ) { Gia_Man_t * pNew; Aig_Obj_t * pObj; int i; // create the new manager pNew = Gia_ManStart( Aig_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); pNew->nConstrs = p->nConstrs; // create the PIs Aig_ManCleanData( p ); Aig_ManForEachObj( p, pObj, i ) { if ( Aig_ObjIsAnd(pObj) ) pObj->iData = Gia_ManAppendAnd( pNew, Gia_ObjChild0Copy(pObj), Gia_ObjChild1Copy(pObj) ); else if ( Aig_ObjIsCi(pObj) ) pObj->iData = Gia_ManAppendCi( pNew ); else if ( Aig_ObjIsCo(pObj) ) pObj->iData = Gia_ManAppendCo( pNew, Gia_ObjChild0Copy(pObj) ); else if ( Aig_ObjIsConst1(pObj) ) pObj->iData = 1; else assert( 0 ); } Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) ); return pNew; }
/**Function************************************************************* Synopsis [Checks the consistency of phase assignment.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManCheckPhase( Aig_Man_t * p ) { Aig_Obj_t * pObj; int i; Aig_ManForEachObj( p, pObj, i ) if ( Aig_ObjIsCi(pObj) ) assert( (int)pObj->fPhase == 0 ); else assert( (int)pObj->fPhase == (Aig_ObjPhaseReal(Aig_ObjChild0(pObj)) & Aig_ObjPhaseReal(Aig_ObjChild1(pObj))) ); }
/**Function************************************************************* Synopsis [Returns 1 if the cone of the node overlaps with the vector.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Aig_ManDeriveNewCone_rec( Aig_Man_t * p, Aig_Obj_t * pNode ) { if ( Aig_ObjIsTravIdCurrent( p, pNode ) ) return (Aig_Obj_t *)pNode->pData; Aig_ObjSetTravIdCurrent( p, pNode ); if ( Aig_ObjIsCi(pNode) ) return (Aig_Obj_t *)(pNode->pData = pNode); Aig_ManDeriveNewCone_rec( p, Aig_ObjFanin0(pNode) ); Aig_ManDeriveNewCone_rec( p, Aig_ObjFanin1(pNode) ); return (Aig_Obj_t *)(pNode->pData = Aig_And( p, Aig_ObjChild0Copy(pNode), Aig_ObjChild1Copy(pNode) )); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Dereferences the node's MFFC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_NodeDeref_rec( Aig_Obj_t * pNode, unsigned LevelMin, float * pPower, float * pProbs ) { float Power0 = 0.0, Power1 = 0.0; Aig_Obj_t * pFanin; int Counter = 0; if ( pProbs ) *pPower = 0.0; if ( Aig_ObjIsCi(pNode) ) return 0; // consider the first fanin pFanin = Aig_ObjFanin0(pNode); assert( pFanin->nRefs > 0 ); if ( --pFanin->nRefs == 0 && (!LevelMin || pFanin->Level > LevelMin) ) Counter += Aig_NodeDeref_rec( pFanin, LevelMin, &Power0, pProbs ); if ( pProbs ) *pPower += Power0 + 2.0 * pProbs[pFanin->Id] * (1.0 - pProbs[pFanin->Id]); // skip the buffer if ( Aig_ObjIsBuf(pNode) ) return Counter; assert( Aig_ObjIsNode(pNode) ); // consider the second fanin pFanin = Aig_ObjFanin1(pNode); assert( pFanin->nRefs > 0 ); if ( --pFanin->nRefs == 0 && (!LevelMin || pFanin->Level > LevelMin) ) Counter += Aig_NodeDeref_rec( pFanin, LevelMin, &Power1, pProbs ); if ( pProbs ) *pPower += Power1 + 2.0 * pProbs[pFanin->Id] * (1.0 - pProbs[pFanin->Id]); return Counter + 1; }
/**Function************************************************************* Synopsis [Returns 1 if the cone of the node overlaps with the vector.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_ManFindConeOverlap_rec( Aig_Man_t * p, Aig_Obj_t * pNode ) { if ( Aig_ObjIsTravIdPrevious( p, pNode ) ) return 1; if ( Aig_ObjIsTravIdCurrent( p, pNode ) ) return 0; Aig_ObjSetTravIdCurrent( p, pNode ); if ( Aig_ObjIsCi(pNode) ) return 0; if ( Aig_ManFindConeOverlap_rec( p, Aig_ObjFanin0(pNode) ) ) return 1; if ( Aig_ManFindConeOverlap_rec( p, Aig_ObjFanin1(pNode) ) ) return 1; return 0; }
/**Function************************************************************* Synopsis [Collects the internal and boundary nodes in the derefed MFFC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_NodeMffcSupp_rec( Aig_Man_t * p, Aig_Obj_t * pNode, unsigned LevelMin, Vec_Ptr_t * vSupp, int fTopmost, Aig_Obj_t * pObjSkip ) { // skip visited nodes if ( Aig_ObjIsTravIdCurrent(p, pNode) ) return; Aig_ObjSetTravIdCurrent(p, pNode); // add to the new support nodes if ( !fTopmost && pNode != pObjSkip && (Aig_ObjIsCi(pNode) || pNode->nRefs > 0 || pNode->Level <= LevelMin) ) { if ( vSupp ) Vec_PtrPush( vSupp, pNode ); return; } assert( Aig_ObjIsNode(pNode) ); // recur on the children Aig_NodeMffcSupp_rec( p, Aig_ObjFanin0(pNode), LevelMin, vSupp, 0, pObjSkip ); Aig_NodeMffcSupp_rec( p, Aig_ObjFanin1(pNode), LevelMin, vSupp, 0, pObjSkip ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Computes area, references, and nodes used in the mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_ManScanMapping_rec( Cnf_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vMapped ) { Aig_Obj_t * pLeaf; Dar_Cut_t * pCutBest; int aArea, i; if ( pObj->nRefs++ || Aig_ObjIsCi(pObj) || Aig_ObjIsConst1(pObj) ) return 0; assert( Aig_ObjIsAnd(pObj) ); // collect the node first to derive pre-order if ( vMapped ) Vec_PtrPush( vMapped, pObj ); // visit the transitive fanin of the selected cut if ( pObj->fMarkB ) { Vec_Ptr_t * vSuper = Vec_PtrAlloc( 100 ); Aig_ObjCollectSuper( pObj, vSuper ); aArea = Vec_PtrSize(vSuper) + 1; Vec_PtrForEachEntry( Aig_Obj_t *, vSuper, pLeaf, i ) aArea += Aig_ManScanMapping_rec( p, Aig_Regular(pLeaf), vMapped ); Vec_PtrFree( vSuper ); //////////////////////////// pObj->fMarkB = 1; }
/**Function************************************************************* Synopsis [References the node's MFFC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_NodeRef_rec( Aig_Obj_t * pNode, unsigned LevelMin ) { Aig_Obj_t * pFanin; int Counter = 0; if ( Aig_ObjIsCi(pNode) ) return 0; // consider the first fanin pFanin = Aig_ObjFanin0(pNode); if ( pFanin->nRefs++ == 0 && (!LevelMin || pFanin->Level > LevelMin) ) Counter += Aig_NodeRef_rec( pFanin, LevelMin ); // skip the buffer if ( Aig_ObjIsBuf(pNode) ) return Counter; assert( Aig_ObjIsNode(pNode) ); // consider the second fanin pFanin = Aig_ObjFanin1(pNode); if ( pFanin->nRefs++ == 0 && (!LevelMin || pFanin->Level > LevelMin) ) Counter += Aig_NodeRef_rec( pFanin, LevelMin ); return Counter + 1; }
/**Function************************************************************* Synopsis [Collects the support of depth-limited MFFC.] Description [Returns the number of internal nodes in the MFFC.] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_NodeMffcSupp( Aig_Man_t * p, Aig_Obj_t * pNode, int LevelMin, Vec_Ptr_t * vSupp ) { int ConeSize1, ConeSize2; if ( vSupp ) Vec_PtrClear( vSupp ); if ( !Aig_ObjIsNode(pNode) ) { if ( Aig_ObjIsCi(pNode) && vSupp ) Vec_PtrPush( vSupp, pNode ); return 0; } assert( !Aig_IsComplement(pNode) ); assert( Aig_ObjIsNode(pNode) ); Aig_ManIncrementTravId( p ); ConeSize1 = Aig_NodeDeref_rec( pNode, LevelMin, NULL, NULL ); Aig_NodeMffcSupp_rec( p, pNode, LevelMin, vSupp, 1, NULL ); ConeSize2 = Aig_NodeRef_rec( pNode, LevelMin ); assert( ConeSize1 == ConeSize2 ); assert( ConeSize1 > 0 ); return ConeSize1; }
/**Function************************************************************* Synopsis [References the node's MFFC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_NodeRefLabel_rec( Aig_Man_t * p, Aig_Obj_t * pNode, unsigned LevelMin ) { Aig_Obj_t * pFanin; int Counter = 0; if ( Aig_ObjIsCi(pNode) ) return 0; Aig_ObjSetTravIdCurrent( p, pNode ); // consider the first fanin pFanin = Aig_ObjFanin0(pNode); if ( pFanin->nRefs++ == 0 && (!LevelMin || pFanin->Level > LevelMin) ) Counter += Aig_NodeRefLabel_rec( p, pFanin, LevelMin ); if ( Aig_ObjIsBuf(pNode) ) return Counter; assert( Aig_ObjIsNode(pNode) ); // consider the second fanin pFanin = Aig_ObjFanin1(pNode); if ( pFanin->nRefs++ == 0 && (!LevelMin || pFanin->Level > LevelMin) ) Counter += Aig_NodeRefLabel_rec( p, pFanin, LevelMin ); return Counter + 1; }
/**Function************************************************************* Synopsis [Drive implications of the given node towards primary outputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Saig_ManSetAndDriveImplications_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int f, int fMax, Vec_Ptr_t * vSimInfo ) { Aig_Obj_t * pFanout; int k, iFanout = -1, Value0, Value1; int Value = Saig_ManSimInfo2Get( vSimInfo, pObj, f ); assert( !Saig_ManSimInfo2IsOld( Value ) ); Saig_ManSimInfo2Set( vSimInfo, pObj, f, Saig_ManSimInfo2SetOld(Value) ); if ( (Aig_ObjIsCo(pObj) && f == fMax) || Saig_ObjIsPo(p, pObj) ) return; if ( Saig_ObjIsLi( p, pObj ) ) { assert( f < fMax ); pFanout = Saig_ObjLiToLo(p, pObj); Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f+1 ); if ( !Saig_ManSimInfo2IsOld( Value ) ) Saig_ManSetAndDriveImplications_rec( p, pFanout, f+1, fMax, vSimInfo ); return; } assert( Aig_ObjIsCi(pObj) || Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) ); Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, k ) { Value = Saig_ManSimInfo2Get( vSimInfo, pFanout, f ); if ( Saig_ManSimInfo2IsOld( Value ) ) continue; if ( Aig_ObjIsCo(pFanout) ) { Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); continue; } assert( Aig_ObjIsNode(pFanout) ); Value0 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin0(pFanout), f ); Value1 = Saig_ManSimInfo2Get( vSimInfo, Aig_ObjFanin1(pFanout), f ); if ( Aig_ObjFaninC0(pFanout) ) Value0 = Saig_ManSimInfo2Not( Value0 ); if ( Aig_ObjFaninC1(pFanout) ) Value1 = Saig_ManSimInfo2Not( Value1 ); if ( Value0 == SAIG_ZER_OLD || Value1 == SAIG_ZER_OLD || (Value0 == SAIG_ONE_OLD && Value1 == SAIG_ONE_OLD) ) Saig_ManSetAndDriveImplications_rec( p, pFanout, f, fMax, vSimInfo ); }
// pNtk->nLatches = Aig_ManRegNum(p); // pNtk->nTruePis = Nwk_ManCiNum(pNtk) - pNtk->nLatches; // pNtk->nTruePos = Nwk_ManCoNum(pNtk) - pNtk->nLatches; Aig_ManForEachObj( p, pObj, i ) { pIfObj = (If_Obj_t *)Vec_PtrEntry( vAigToIf, i ); if ( pIfObj->nRefs == 0 && !If_ObjIsTerm(pIfObj) ) continue; if ( Aig_ObjIsNode(pObj) ) { pCutBest = If_ObjCutBest( pIfObj ); nLeaves = If_CutLeaveNum( pCutBest ); ppLeaves = If_CutLeaves( pCutBest ); // create node pObjNew = Nwk_ManCreateNode( pNtk, nLeaves, pIfObj->nRefs ); for ( k = 0; k < nLeaves; k++ ) { pObjRepr = (Aig_Obj_t *)Vec_PtrEntry( vIfToAig, ppLeaves[k] ); Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)pObjRepr->pData ); } // get the functionality pObjNew->pFunc = Nwk_NodeIfToHop( pNtk->pManHop, pIfMan, pIfObj ); } else if ( Aig_ObjIsCi(pObj) ) pObjNew = Nwk_ManCreateCi( pNtk, pIfObj->nRefs ); else if ( Aig_ObjIsCo(pObj) ) { pObjNew = Nwk_ManCreateCo( pNtk ); pObjNew->fInvert = Aig_ObjFaninC0(pObj); Nwk_ObjAddFanin( pObjNew, (Nwk_Obj_t *)Aig_ObjFanin0(pObj)->pData ); //printf( "%d ", pObjNew->Id ); } else if ( Aig_ObjIsConst1(pObj) ) { pObjNew = Nwk_ManCreateNode( pNtk, 0, pIfObj->nRefs ); pObjNew->pFunc = Hop_ManConst1( pNtk->pManHop ); } else assert( 0 ); pObj->pData = pObjNew; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Adds strashed nodes for one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_ManSpeedupNode_rec( Aig_Man_t * pAig, Aig_Obj_t * pNode, Vec_Ptr_t * vNodes ) { if ( Aig_ObjIsTravIdCurrent(pAig, pNode) ) return 1; if ( Aig_ObjIsCi(pNode) ) return 0; assert( Aig_ObjIsNode(pNode) ); Aig_ObjSetTravIdCurrent( pAig, pNode ); if ( !Aig_ManSpeedupNode_rec( pAig, Aig_ObjFanin0(pNode), vNodes ) ) return 0; if ( !Aig_ManSpeedupNode_rec( pAig, Aig_ObjFanin1(pNode), vNodes ) ) return 0; Vec_PtrPush( vNodes, pNode ); return 1; }
/**Function************************************************************* Synopsis [Performs induction by unrolling timeframes backward.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fGetCex, int fVerbose, int fVeryVerbose ) { sat_solver * pSat; Aig_Man_t * pAigPart; Cnf_Dat_t * pCnfPart; Vec_Int_t * vTopVarNums, * vState, * vTopVarIds = NULL; Vec_Ptr_t * vTop, * vBot; Aig_Obj_t * pObjPi, * pObjPiCopy, * pObjPo; int i, k, f, Lits[2], status = -1, RetValue, nSatVarNum, nConfPrev; int nOldSize, iReg, iLast, fAdded, nConstrs = 0, nClauses = 0; abctime clk; assert( fUnique == 0 || fUniqueAll == 0 ); assert( Saig_ManPoNum(p) == 1 ); Aig_ManSetCioIds( p ); // start the top by including the PO vBot = Vec_PtrAlloc( 100 ); vTop = Vec_PtrAlloc( 100 ); vState = Vec_IntAlloc( 1000 ); Vec_PtrPush( vTop, Aig_ManCo(p, 0) ); // start the array of CNF variables vTopVarNums = Vec_IntAlloc( 100 ); // start the solver pSat = sat_solver_new(); sat_solver_setnvars( pSat, 1000 ); // iterate backward unrolling RetValue = -1; nSatVarNum = 0; if ( fVerbose ) printf( "Induction parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax ); for ( f = 0; ; f++ ) { if ( f > 0 ) { Aig_ManStop( pAigPart ); Cnf_DataFree( pCnfPart ); } clk = Abc_Clock(); // get the bottom Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vTop), Vec_PtrSize(vTop), vBot ); // derive AIG for the part between top and bottom pAigPart = Aig_ManDupSimpleDfsPart( p, vBot, vTop ); // convert it into CNF pCnfPart = Cnf_Derive( pAigPart, Aig_ManCoNum(pAigPart) ); Cnf_DataLift( pCnfPart, nSatVarNum ); nSatVarNum += pCnfPart->nVars; nClauses += pCnfPart->nClauses; // remember top frame var IDs if ( fGetCex && vTopVarIds == NULL ) { vTopVarIds = Vec_IntStartFull( Aig_ManCiNum(p) ); Aig_ManForEachCi( p, pObjPi, i ) { if ( pObjPi->pData == NULL ) continue; pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; assert( Aig_ObjIsCi(pObjPiCopy) ); if ( Saig_ObjIsPi(p, pObjPi) ) Vec_IntWriteEntry( vTopVarIds, Aig_ObjCioId(pObjPi) + Saig_ManRegNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] ); else if ( Saig_ObjIsLo(p, pObjPi) ) Vec_IntWriteEntry( vTopVarIds, Aig_ObjCioId(pObjPi) - Saig_ManPiNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] ); else assert( 0 ); } } // stitch variables of top and bot assert( Aig_ManCoNum(pAigPart)-1 == Vec_IntSize(vTopVarNums) ); Aig_ManForEachCo( pAigPart, pObjPo, i ) { if ( i == 0 ) { // do not perform inductive strengthening // if ( f > 0 ) // continue; // add topmost literal Lits[0] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], f>0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) ) assert( 0 ); nClauses++; continue; } Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 0 ); Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 1 ); Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); nClauses += 2; } // add CNF to the SAT solver for ( i = 0; i < pCnfPart->nClauses; i++ ) if ( !sat_solver_addclause( pSat, pCnfPart->pClauses[i], pCnfPart->pClauses[i+1] ) ) break; if ( i < pCnfPart->nClauses ) { // printf( "SAT solver became UNSAT after adding clauses.\n" ); RetValue = 1; break; } // create new set of POs to derive new top Vec_PtrClear( vTop ); Vec_PtrPush( vTop, Aig_ManCo(p, 0) ); Vec_IntClear( vTopVarNums ); nOldSize = Vec_IntSize(vState); Vec_IntFillExtra( vState, nOldSize + Aig_ManRegNum(p), -1 ); Vec_PtrForEachEntry( Aig_Obj_t *, vBot, pObjPi, i ) { assert( Aig_ObjIsCi(pObjPi) ); if ( Saig_ObjIsLo(p, pObjPi) ) { pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; assert( pObjPiCopy != NULL ); Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) ); Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] ); iReg = pObjPi->CioId - Saig_ManPiNum(p); assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); Vec_IntWriteEntry( vState, nOldSize+iReg, pCnfPart->pVarNums[pObjPiCopy->Id] ); } }
/**Function************************************************************* Synopsis [Load the network into FPGA manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ If_Man_t * Nwk_ManToIf( Aig_Man_t * p, If_Par_t * pPars, Vec_Ptr_t * vAigToIf ) { extern Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * p, int nFrames, int nPref, int fProbOne ); Vec_Int_t * vSwitching = NULL, * vSwitching2 = NULL; float * pSwitching = NULL, * pSwitching2 = NULL; If_Man_t * pIfMan; If_Obj_t * pIfObj; Aig_Obj_t * pNode, * pFanin, * pPrev; int i; abctime clk = Abc_Clock(); // set the number of registers (switch activity will be combinational) Aig_ManSetRegNum( p, 0 ); if ( pPars->fPower ) { vSwitching = Saig_ManComputeSwitchProbs( p, 48, 16, 0 ); if ( pPars->fVerbose ) { ABC_PRT( "Computing switching activity", Abc_Clock() - clk ); } pSwitching = (float *)vSwitching->pArray; vSwitching2 = Vec_IntStart( Aig_ManObjNumMax(p) ); pSwitching2 = (float *)vSwitching2->pArray; } // start the mapping manager and set its parameters pIfMan = If_ManStart( pPars ); pIfMan->vSwitching = vSwitching2; // load the AIG into the mapper Aig_ManForEachObj( p, pNode, i ) { if ( Aig_ObjIsAnd(pNode) ) { pIfObj = If_ManCreateAnd( pIfMan, If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ), If_NotCond( (If_Obj_t *)Aig_ObjFanin1(pNode)->pData, Aig_ObjFaninC1(pNode) ) ); // printf( "no%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); } else if ( Aig_ObjIsCi(pNode) ) { pIfObj = If_ManCreateCi( pIfMan ); If_ObjSetLevel( pIfObj, Aig_ObjLevel(pNode) ); // printf( "pi%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); if ( pIfMan->nLevelMax < (int)pIfObj->Level ) pIfMan->nLevelMax = (int)pIfObj->Level; } else if ( Aig_ObjIsCo(pNode) ) { pIfObj = If_ManCreateCo( pIfMan, If_NotCond( (If_Obj_t *)Aig_ObjFanin0(pNode)->pData, Aig_ObjFaninC0(pNode) ) ); // printf( "po%d=%d\n ", If_ObjId(pIfObj), If_ObjLevel(pIfObj) ); } else if ( Aig_ObjIsConst1(pNode) ) pIfObj = If_ManConst1( pIfMan ); else // add the node to the mapper assert( 0 ); // save the result assert( Vec_PtrEntry(vAigToIf, i) == NULL ); Vec_PtrWriteEntry( vAigToIf, i, pIfObj ); pNode->pData = pIfObj; if ( vSwitching2 ) pSwitching2[pIfObj->Id] = pSwitching[pNode->Id]; // set up the choice node if ( Aig_ObjIsChoice( p, pNode ) ) { for ( pPrev = pNode, pFanin = Aig_ObjEquiv(p, pNode); pFanin; pPrev = pFanin, pFanin = Aig_ObjEquiv(p, pFanin) ) If_ObjSetChoice( (If_Obj_t *)pPrev->pData, (If_Obj_t *)pFanin->pData ); If_ManCreateChoice( pIfMan, (If_Obj_t *)pNode->pData ); } // assert( If_ObjLevel(pIfObj) == Aig_ObjLevel(pNode) ); } if ( vSwitching ) Vec_IntFree( vSwitching ); return pIfMan; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManInterTest( Aig_Man_t * pMan, int fVerbose ) { sat_solver2 * pSat; // Aig_Man_t * pInter; word * pInter; Vec_Int_t * vVars; Cnf_Dat_t * pCnf; Aig_Obj_t * pObj; int Lit, Cid, Var, status, i; clock_t clk = clock(); assert( Aig_ManRegNum(pMan) == 0 ); assert( Aig_ManCoNum(pMan) == 1 ); // derive CNFs pCnf = Cnf_Derive( pMan, 1 ); // start the solver pSat = sat_solver2_new(); sat_solver2_setnvars( pSat, 2*pCnf->nVars+1 ); // set A-variables (all used except PI/PO) Aig_ManForEachObj( pMan, pObj, i ) { if ( pCnf->pVarNums[pObj->Id] < 0 ) continue; if ( !Aig_ObjIsCi(pObj) && !Aig_ObjIsCo(pObj) ) var_set_partA( pSat, pCnf->pVarNums[pObj->Id], 1 ); } // add clauses of A for ( i = 0; i < pCnf->nClauses; i++ ) { Cid = sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); clause2_set_partA( pSat, Cid, 1 ); } // add clauses of B Cnf_DataLift( pCnf, pCnf->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); Cnf_DataLift( pCnf, -pCnf->nVars ); // add PI equality clauses vVars = Vec_IntAlloc( Aig_ManCoNum(pMan)+1 ); Aig_ManForEachCi( pMan, pObj, i ) { if ( Aig_ObjRefs(pObj) == 0 ) continue; Var = pCnf->pVarNums[pObj->Id]; Aig_ManInterAddBuffer( pSat, Var, pCnf->nVars + Var, 0, 0 ); Vec_IntPush( vVars, Var ); } // add an XOR clause in the end Var = pCnf->pVarNums[Aig_ManCo(pMan,0)->Id]; Aig_ManInterAddXor( pSat, Var, pCnf->nVars + Var, 2*pCnf->nVars, 0, 0 ); Vec_IntPush( vVars, Var ); // solve the problem Lit = toLitCond( 2*pCnf->nVars, 0 ); status = sat_solver2_solve( pSat, &Lit, &Lit + 1, 0, 0, 0, 0 ); assert( status == l_False ); Sat_Solver2PrintStats( stdout, pSat ); // derive interpolant // pInter = Sat_ProofInterpolant( pSat, vVars ); // Aig_ManPrintStats( pInter ); // Aig_ManDumpBlif( pInter, "int.blif", NULL, NULL ); //pInter = Sat_ProofInterpolantTruth( pSat, vVars ); pInter = NULL; // Extra_PrintHex( stdout, pInter, Vec_IntSize(vVars) ); printf( "\n" ); // clean up // Aig_ManStop( pInter ); ABC_FREE( pInter ); Vec_IntFree( vVars ); Cnf_DataFree( pCnf ); sat_solver2_delete( pSat ); ABC_PRT( "Total interpolation time", clock() - clk ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Performs one retiming step forward.] Description [Returns the pointer to the register output after retiming.] SideEffects [Remember to run Aig_ManSetCioIds() in advance.] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Saig_ManRetimeNodeFwd( Aig_Man_t * p, Aig_Obj_t * pObj, int fMakeBug ) { Aig_Obj_t * pFanin0, * pFanin1; Aig_Obj_t * pInput0, * pInput1; Aig_Obj_t * pObjNew, * pObjLi, * pObjLo; int fCompl; assert( Saig_ManRegNum(p) > 0 ); assert( Aig_ObjIsNode(pObj) ); // get the fanins pFanin0 = Aig_ObjFanin0(pObj); pFanin1 = Aig_ObjFanin1(pObj); // skip of they are not primary inputs if ( !Aig_ObjIsCi(pFanin0) || !Aig_ObjIsCi(pFanin1) ) return NULL; // skip of they are not register outputs if ( !Saig_ObjIsLo(p, pFanin0) || !Saig_ObjIsLo(p, pFanin1) ) return NULL; assert( Aig_ObjCioId(pFanin0) > 0 ); assert( Aig_ObjCioId(pFanin1) > 0 ); // skip latch guns if ( !Aig_ObjIsTravIdCurrent(p, pFanin0) && !Aig_ObjIsTravIdCurrent(p, pFanin1) ) return NULL; // get the inputs of these registers pInput0 = Saig_ManLi( p, Aig_ObjCioId(pFanin0) - Saig_ManPiNum(p) ); pInput1 = Saig_ManLi( p, Aig_ObjCioId(pFanin1) - Saig_ManPiNum(p) ); pInput0 = Aig_ObjChild0( pInput0 ); pInput1 = Aig_ObjChild0( pInput1 ); pInput0 = Aig_NotCond( pInput0, Aig_ObjFaninC0(pObj) ); pInput1 = Aig_NotCond( pInput1, Aig_ObjFaninC1(pObj) ); // get the condition when the register should be complemetned fCompl = Aig_ObjFaninC0(pObj) && Aig_ObjFaninC1(pObj); if ( fMakeBug ) { printf( "Introducing bug during retiming.\n" ); pInput1 = Aig_Not( pInput1 ); } // create new node pObjNew = Aig_And( p, pInput0, pInput1 ); // create new register input pObjLi = Aig_ObjCreateCo( p, Aig_NotCond(pObjNew, fCompl) ); pObjLi->CioId = Aig_ManCoNum(p) - 1; // create new register output pObjLo = Aig_ObjCreateCi( p ); pObjLo->CioId = Aig_ManCiNum(p) - 1; p->nRegs++; // make sure the register is retimable. Aig_ObjSetTravIdCurrent(p, pObjLo); //printf( "Reg = %4d. Reg = %4d. Compl = %d. Phase = %d.\n", // pFanin0->PioNum, pFanin1->PioNum, Aig_IsComplement(pObjNew), fCompl ); // return register output return Aig_NotCond( pObjLo, fCompl ); }
int Pdr_ObjSatVar2( Pdr_Man_t * p, int k, Aig_Obj_t * pObj, int Level, int Pol ) { Vec_Int_t * vLits; sat_solver * pSat; Vec_Int_t * vVar2Ids = (Vec_Int_t *)Vec_PtrEntry(&p->vVar2Ids, k); int nVarCount = Vec_IntSize(vVar2Ids); int iVarThis = Pdr_ObjSatVar2FindOrAdd( p, k, pObj ); int * pLit, i, iVar, iClaBeg, iClaEnd, RetValue; int PolPres = (iVarThis & 3); iVarThis >>= 2; if ( Aig_ObjIsCi(pObj) ) return iVarThis; // Pol = 3; // if ( nVarCount != Vec_IntSize(vVar2Ids) || (Pol & ~PolPres) ) if ( (Pol & ~PolPres) ) { *Vec_IntEntryP( p->pvId2Vars + Aig_ObjId(pObj), k ) |= Pol; iClaBeg = p->pCnf2->pObj2Clause[Aig_ObjId(pObj)]; iClaEnd = iClaBeg + p->pCnf2->pObj2Count[Aig_ObjId(pObj)]; assert( iClaBeg < iClaEnd ); /* if ( (Pol & ~PolPres) != 3 ) for ( i = iFirstClause; i < iFirstClause + nClauses; i++ ) { printf( "Clause %5d : ", i ); for ( iVar = 0; iVar < 4; iVar++ ) printf( "%d ", ((unsigned)p->pCnf2->pClaPols[i] >> (2*iVar)) & 3 ); printf( " " ); for ( pLit = p->pCnf2->pClauses[i]; pLit < p->pCnf2->pClauses[i+1]; pLit++ ) printf( "%6d ", *pLit ); printf( "\n" ); } */ pSat = Pdr_ManSolver(p, k); vLits = Vec_WecEntry( p->vVLits, Level ); if ( (Pol & ~PolPres) == 3 ) { assert( nVarCount + 1 == Vec_IntSize(vVar2Ids) ); for ( i = iClaBeg; i < iClaEnd; i++ ) { Vec_IntClear( vLits ); Vec_IntPush( vLits, toLitCond( iVarThis, lit_sign(p->pCnf2->pClauses[i][0]) ) ); for ( pLit = p->pCnf2->pClauses[i]+1; pLit < p->pCnf2->pClauses[i+1]; pLit++ ) { iVar = Pdr_ObjSatVar2( p, k, Aig_ManObj(p->pAig, lit_var(*pLit)), Level+1, 3 ); Vec_IntPush( vLits, toLitCond( iVar, lit_sign(*pLit) ) ); } RetValue = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits)+Vec_IntSize(vLits) ); assert( RetValue ); (void) RetValue; } } else // if ( (Pol & ~PolPres) == 2 || (Pol & ~PolPres) == 1 ) // write pos/neg polarity { assert( (Pol & ~PolPres) ); for ( i = iClaBeg; i < iClaEnd; i++ ) if ( 2 - !Abc_LitIsCompl(p->pCnf2->pClauses[i][0]) == (Pol & ~PolPres) ) // taking opposite literal { Vec_IntClear( vLits ); Vec_IntPush( vLits, toLitCond( iVarThis, Abc_LitIsCompl(p->pCnf2->pClauses[i][0]) ) ); for ( pLit = p->pCnf2->pClauses[i]+1; pLit < p->pCnf2->pClauses[i+1]; pLit++ ) { iVar = Pdr_ObjSatVar2( p, k, Aig_ManObj(p->pAig, lit_var(*pLit)), Level+1, ((unsigned)p->pCnf2->pClaPols[i] >> (2*(pLit-p->pCnf2->pClauses[i]-1))) & 3 ); Vec_IntPush( vLits, toLitCond( iVar, lit_sign(*pLit) ) ); } RetValue = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits)+Vec_IntSize(vLits) ); assert( RetValue ); (void) RetValue; } }