/**Function************************************************************* Synopsis [Performs clock-gating for the AIG.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Cgt_ClockGatingRangeCheck( Cgt_Man_t * p, int iStart, int nOutputs ) { Vec_Ptr_t * vNodes = p->vFanout; Aig_Obj_t * pMiter, * pCand, * pMiterFrame, * pCandFrame, * pMiterPart, * pCandPart; int i, k, RetValue, nCalls; assert( Vec_VecSize(p->vGatesAll) == Aig_ManPoNum(p->pFrame) ); // go through all the registers inputs of this range for ( i = iStart; i < iStart + nOutputs; i++ ) { nCalls = p->nCalls; pMiter = Saig_ManLi( p->pAig, i ); Cgt_ManDetectCandidates( p->pAig, Aig_ObjFanin0(pMiter), p->pPars->nLevelMax, vNodes ); // go through the candidates of this PO Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pCand, k ) { // get the corresponding nodes from the frames pCandFrame = (Aig_Obj_t *)pCand->pData; pMiterFrame = (Aig_Obj_t *)pMiter->pData; // get the corresponding nodes from the part pCandPart = (Aig_Obj_t *)pCandFrame->pData; pMiterPart = (Aig_Obj_t *)pMiterFrame->pData; // try direct polarity if ( Cgt_SimulationFilter( p, pCandPart, pMiterPart ) ) { RetValue = Cgt_CheckImplication( p, pCandPart, pMiterPart ); if ( RetValue == 1 ) { Vec_VecPush( p->vGatesAll, i, pCand ); continue; } if ( RetValue == 0 ) Cgt_SimulationRecord( p ); } else p->nCallsFiltered++; // try reverse polarity if ( Cgt_SimulationFilter( p, Aig_Not(pCandPart), pMiterPart ) ) { RetValue = Cgt_CheckImplication( p, Aig_Not(pCandPart), pMiterPart ); if ( RetValue == 1 ) { Vec_VecPush( p->vGatesAll, i, Aig_Not(pCand) ); continue; } if ( RetValue == 0 ) Cgt_SimulationRecord( p ); } else p->nCallsFiltered++; } if ( p->pPars->fVerbose ) { // printf( "Flop %3d : Cand = %4d. Gate = %4d. SAT calls = %3d.\n", // i, Vec_PtrSize(vNodes), Vec_PtrSize(Vec_VecEntry(p->vGatesAll, i)), p->nCalls-nCalls ); } }
/**Function************************************************************* Synopsis [Performs one retiming step backward.] Description [Returns the pointer to node after retiming.] SideEffects [Remember to run Aig_ManSetCioIds() in advance.] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Saig_ManRetimeNodeBwd( Aig_Man_t * p, Aig_Obj_t * pObjLo ) { Aig_Obj_t * pFanin0, * pFanin1; Aig_Obj_t * pLo0New, * pLo1New; Aig_Obj_t * pLi0New, * pLi1New; Aig_Obj_t * pObj, * pObjNew, * pObjLi; int fCompl0, fCompl1; assert( Saig_ManRegNum(p) > 0 ); assert( Aig_ObjCioId(pObjLo) > 0 ); assert( Saig_ObjIsLo(p, pObjLo) ); // get the corresponding latch input pObjLi = Saig_ManLi( p, Aig_ObjCioId(pObjLo) - Saig_ManPiNum(p) ); // get the node pObj = Aig_ObjFanin0(pObjLi); if ( !Aig_ObjIsNode(pObj) ) return NULL; // get the fanins pFanin0 = Aig_ObjFanin0(pObj); pFanin1 = Aig_ObjFanin1(pObj); // get the complemented attributes of the fanins fCompl0 = Aig_ObjFaninC0(pObj) ^ Aig_ObjFaninC0(pObjLi); fCompl1 = Aig_ObjFaninC1(pObj) ^ Aig_ObjFaninC0(pObjLi); // create latch inputs pLi0New = Aig_ObjCreateCo( p, Aig_NotCond(pFanin0, fCompl0) ); pLi0New->CioId = Aig_ManCoNum(p) - 1; pLi1New = Aig_ObjCreateCo( p, Aig_NotCond(pFanin1, fCompl1) ); pLi1New->CioId = Aig_ManCoNum(p) - 1; // create latch outputs pLo0New = Aig_ObjCreateCi(p); pLo0New->CioId = Aig_ManCiNum(p) - 1; pLo1New = Aig_ObjCreateCi(p); pLo1New->CioId = Aig_ManCiNum(p) - 1; pLo0New = Aig_NotCond( pLo0New, fCompl0 ); pLo1New = Aig_NotCond( pLo1New, fCompl1 ); p->nRegs += 2; // create node pObjNew = Aig_And( p, pLo0New, pLo1New ); // assert( pObjNew->fPhase == 0 ); return pObjNew; }
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 ); }