/**Function************************************************************* Synopsis [Collects internal nodes in the DFS order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManDfs_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) { if ( pObj == NULL ) return; assert( !Aig_IsComplement(pObj) ); if ( Aig_ObjIsTravIdCurrent(p, pObj) ) return; assert( Aig_ObjIsNode(pObj) || Aig_ObjIsBuf(pObj) ); Aig_ManDfs_rec( p, Aig_ObjFanin0(pObj), vNodes ); Aig_ManDfs_rec( p, Aig_ObjFanin1(pObj), vNodes ); assert( !Aig_ObjIsTravIdCurrent(p, pObj) ); // loop detection Aig_ObjSetTravIdCurrent(p, pObj); Vec_PtrPush( vNodes, pObj ); }
/**Function************************************************************* Synopsis [Collects internal nodes in the reverse DFS order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManDfsReverse_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes ) { Aig_Obj_t * pFanout; int iFanout, i; assert( !Aig_IsComplement(pObj) ); if ( Aig_ObjIsTravIdCurrent(p, pObj) ) return; assert( Aig_ObjIsNode(pObj) || Aig_ObjIsBuf(pObj) ); Aig_ObjForEachFanout( p, pObj, pFanout, iFanout, i ) Aig_ManDfsReverse_rec( p, pFanout, vNodes ); assert( !Aig_ObjIsTravIdCurrent(p, pObj) ); // loop detection Aig_ObjSetTravIdCurrent(p, pObj); Vec_PtrPush( vNodes, 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) )); }
Kit_GraphForEachNode( pGraph, pNode, i ) { // get the children of this node pNode0 = Kit_GraphNode( pGraph, pNode->eEdge0.Node ); pNode1 = Kit_GraphNode( pGraph, pNode->eEdge1.Node ); // get the AIG nodes corresponding to the children pAnd0 = pNode0->pFunc; pAnd1 = pNode1->pFunc; if ( pAnd0 && pAnd1 ) { // if they are both present, find the resulting node pAnd0 = Aig_NotCond( pAnd0, pNode->eEdge0.fCompl ); pAnd1 = Aig_NotCond( pAnd1, pNode->eEdge1.fCompl ); pAnd = Aig_TableLookupTwo( pAig, pAnd0, pAnd1 ); // return -1 if the node is the same as the original root if ( Aig_Regular(pAnd) == pRoot ) return -1; } else pAnd = NULL; // count the number of added nodes if ( pAnd == NULL || Aig_ObjIsTravIdCurrent(pAig, Aig_Regular(pAnd)) ) { if ( ++Counter > NodeMax ) return -1; } // count the number of new levels LevelNew = 1 + AIG_MAX( pNode0->Level, pNode1->Level ); if ( pAnd ) { if ( Aig_Regular(pAnd) == Aig_ManConst1(pAig) ) LevelNew = 0; else if ( Aig_Regular(pAnd) == Aig_Regular(pAnd0) ) LevelNew = (int)Aig_Regular(pAnd0)->Level; else if ( Aig_Regular(pAnd) == Aig_Regular(pAnd1) ) LevelNew = (int)Aig_Regular(pAnd1)->Level; LevelOld = (int)Aig_Regular(pAnd)->Level; // assert( LevelNew == LevelOld ); } if ( LevelNew > LevelMax ) return -1; pNode->pFunc = pAnd; pNode->Level = LevelNew; /* printf( "Checking " ); Ref_ObjPrint( pAnd0 ); printf( " and " ); Ref_ObjPrint( pAnd1 ); printf( " Result " ); Ref_ObjPrint( pNode->pFunc ); printf( "\n" ); */ }
/**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 POs in the transitive fanout.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Cgt_ManCollectFanoutPos_rec( Aig_Man_t * pAig, Aig_Obj_t * pObj, Vec_Ptr_t * vFanout ) { Aig_Obj_t * pFanout; int f, iFanout = -1; if ( Aig_ObjIsTravIdCurrent(pAig, pObj) ) return; Aig_ObjSetTravIdCurrent(pAig, pObj); if ( Aig_ObjIsCo(pObj) ) { Vec_PtrPush( vFanout, pObj ); return; } Aig_ObjForEachFanout( pAig, pObj, pFanout, iFanout, f ) Cgt_ManCollectFanoutPos_rec( pAig, pFanout, vFanout ); }
/**Function************************************************************* Synopsis [Collects the internal and boundary nodes in the derefed MFFC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_NodeMffsSupp_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_ObjIsPi(pNode) || pNode->nRefs > 0 || pNode->Level <= LevelMin) ) { if ( vSupp ) Vec_PtrPush( vSupp, pNode ); return; } assert( Aig_ObjIsNode(pNode) ); // recur on the children Aig_NodeMffsSupp_rec( p, Aig_ObjFanin0(pNode), LevelMin, vSupp, 0, pObjSkip ); Aig_NodeMffsSupp_rec( p, Aig_ObjFanin1(pNode), LevelMin, vSupp, 0, pObjSkip ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Llb_ManTracePaths_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pPivot ) { Aig_Obj_t * pFanout; int k, iFan; if ( Aig_ObjIsTravIdPrevious(p, pObj) ) return 0; if ( Aig_ObjIsTravIdCurrent(p, pObj) ) return 1; if ( Saig_ObjIsLi(p, pObj) ) return 0; if ( Saig_ObjIsPo(p, pObj) ) return 0; if ( pObj == pPivot ) return 1; assert( Aig_ObjIsCand(pObj) ); Aig_ObjForEachFanout( p, pObj, pFanout, iFan, k ) if ( !Llb_ManTracePaths_rec( p, pFanout, pPivot ) ) { Aig_ObjSetTravIdPrevious(p, pObj); return 0; } Aig_ObjSetTravIdCurrent(p, pObj); return 1; }
/**Function************************************************************* Synopsis [Adds relevant constraints.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Obj_t * Abc_NtkConstructCare_rec( Aig_Man_t * pCare, Aig_Obj_t * pObj, Aig_Man_t * pMan ) { Aig_Obj_t * pObj0, * pObj1; if ( Aig_ObjIsTravIdCurrent( pCare, pObj ) ) return (Aig_Obj_t *)pObj->pData; Aig_ObjSetTravIdCurrent( pCare, pObj ); if ( Aig_ObjIsPi(pObj) ) return (Aig_Obj_t *)(pObj->pData = NULL); pObj0 = Abc_NtkConstructCare_rec( pCare, Aig_ObjFanin0(pObj), pMan ); if ( pObj0 == NULL ) return (Aig_Obj_t *)(pObj->pData = NULL); pObj1 = Abc_NtkConstructCare_rec( pCare, Aig_ObjFanin1(pObj), pMan ); if ( pObj1 == NULL ) return (Aig_Obj_t *)(pObj->pData = NULL); pObj0 = Aig_NotCond( pObj0, Aig_ObjFaninC0(pObj) ); pObj1 = Aig_NotCond( pObj1, Aig_ObjFaninC1(pObj) ); return (Aig_Obj_t *)(pObj->pData = Aig_And( pMan, pObj0, pObj1 )); }
/**Function************************************************************* Synopsis [Creates AIG for the window with constraints.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Abc_NtkConstructAig( Mfs_Man_t * p, Abc_Obj_t * pNode ) { Aig_Man_t * pMan; Abc_Obj_t * pFanin; Aig_Obj_t * pObjAig, * pPi, * pPo; Vec_Int_t * vOuts; int i, k, iOut; // start the new manager pMan = Aig_ManStart( 1000 ); // construct the root node's AIG cone pObjAig = Abc_NtkConstructAig_rec( p, pNode, pMan ); // assert( Aig_ManConst1(pMan) == pObjAig ); Aig_ObjCreatePo( pMan, pObjAig ); if ( p->pCare ) { // mark the care set Aig_ManIncrementTravId( p->pCare ); Vec_PtrForEachEntry( Abc_Obj_t *, p->vSupp, pFanin, i ) { pPi = Aig_ManPi( p->pCare, (int)(ABC_PTRUINT_T)pFanin->pData ); Aig_ObjSetTravIdCurrent( p->pCare, pPi ); pPi->pData = pFanin->pCopy; } // construct the constraints Vec_PtrForEachEntry( Abc_Obj_t *, p->vSupp, pFanin, i ) { vOuts = (Vec_Int_t *)Vec_PtrEntry( p->vSuppsInv, (int)(ABC_PTRUINT_T)pFanin->pData ); Vec_IntForEachEntry( vOuts, iOut, k ) { pPo = Aig_ManPo( p->pCare, iOut ); if ( Aig_ObjIsTravIdCurrent( p->pCare, pPo ) ) continue; Aig_ObjSetTravIdCurrent( p->pCare, pPo ); if ( Aig_ObjFanin0(pPo) == Aig_ManConst1(p->pCare) ) continue; pObjAig = Abc_NtkConstructCare_rec( p->pCare, Aig_ObjFanin0(pPo), pMan ); if ( pObjAig == NULL ) continue; pObjAig = Aig_NotCond( pObjAig, Aig_ObjFaninC0(pPo) ); Aig_ObjCreatePo( pMan, pObjAig ); } }
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_ObjIsPi(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 [Sets variable activities in the cone.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_SetActivityFactors_rec( Fra_Man_t * p, Aig_Obj_t * pObj, int LevelMin, int LevelMax ) { Vec_Ptr_t * vFanins; Aig_Obj_t * pFanin; int i, Counter = 0; assert( !Aig_IsComplement(pObj) ); assert( Fra_ObjSatNum(pObj) ); // skip visited variables if ( Aig_ObjIsTravIdCurrent(p->pManFraig, pObj) ) return 0; Aig_ObjSetTravIdCurrent(p->pManFraig, pObj); // add the PI to the list if ( pObj->Level <= (unsigned)LevelMin || Aig_ObjIsPi(pObj) ) return 0; // set the factor of this variable // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pPars->dActConeBumpMax / ThisBump p->pSat->factors[Fra_ObjSatNum(pObj)] = p->pPars->dActConeBumpMax * (pObj->Level - LevelMin)/(LevelMax - LevelMin); veci_push(&p->pSat->act_vars, Fra_ObjSatNum(pObj)); // explore the fanins vFanins = Fra_ObjFaninVec( pObj ); Vec_PtrForEachEntry( vFanins, pFanin, i ) Counter += Fra_SetActivityFactors_rec( p, Aig_Regular(pFanin), LevelMin, LevelMax ); return 1 + Counter; }
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 ); }