/**Function************************************************************* Synopsis [Returns PI arrival time.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float Aig_TManGetPiArrival( Aig_TMan_t * p, int iPi ) { Aig_TBox_t * pBox; Aig_TObj_t * pObj; float DelayMax; int i; assert( iPi < p->nPis ); if ( p->pPis[iPi].iObj2Box < 0 ) return p->pPis[iPi].timeOffset; pBox = Vec_PtrEntry( p->vBoxes, p->pPis[iPi].iObj2Box ); // check if box timing is updated if ( pBox->TravId == p->nTravIds ) return p->pPis[iPi].timeOffset; pBox->TravId = p->nTravIds; // update box timing DelayMax = -1.0e+20F; for ( i = 0; i < pBox->nOutputs; i++ ) { pObj = p->pPos + pBox->Inouts[pBox->nInputs+i]; DelayMax = AIG_MAX( DelayMax, pObj->timeActual + pObj->timeOffset ); } for ( i = 0; i < pBox->nInputs; i++ ) { pObj = p->pPis + pBox->Inouts[i]; pObj->timeActual = DelayMax + pObj->timeOffset; } return p->pPis[iPi].timeActual; }
/**Function************************************************************* Synopsis [Replaces one object by another.] Description [The new object (pObjNew) should be used instead of the old object (pObjOld). If the new object is complemented or used, the buffer is added and the new object remains in the manager; otherwise, the new object is deleted.] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ObjReplace( Aig_Man_t * p, Aig_Obj_t * pObjOld, Aig_Obj_t * pObjNew, int fNodesOnly, int fUpdateLevel ) { Aig_Obj_t * pObjNewR = Aig_Regular(pObjNew); // the object to be replaced cannot be complemented assert( !Aig_IsComplement(pObjOld) ); // the object to be replaced cannot be a terminal assert( !Aig_ObjIsPi(pObjOld) && !Aig_ObjIsPo(pObjOld) ); // the object to be used cannot be a buffer or a PO assert( !Aig_ObjIsBuf(pObjNewR) && !Aig_ObjIsPo(pObjNewR) ); // the object cannot be the same assert( pObjOld != pObjNewR ); // make sure object is not pointing to itself assert( pObjOld != Aig_ObjFanin0(pObjNewR) ); assert( pObjOld != Aig_ObjFanin1(pObjNewR) ); // recursively delete the old node - but leave the object there pObjNewR->nRefs++; Aig_ObjDelete_rec( p, pObjOld, 0 ); pObjNewR->nRefs--; // if the new object is complemented or already used, create a buffer p->nObjs[pObjOld->Type]--; if ( Aig_IsComplement(pObjNew) || Aig_ObjRefs(pObjNew) > 0 || (fNodesOnly && !Aig_ObjIsNode(pObjNew)) ) { pObjOld->Type = AIG_OBJ_BUF; Aig_ObjConnect( p, pObjOld, pObjNew, NULL ); p->nBufReplaces++; } else { Aig_Obj_t * pFanin0 = pObjNew->pFanin0; Aig_Obj_t * pFanin1 = pObjNew->pFanin1; int LevelOld = pObjOld->Level; pObjOld->Type = pObjNew->Type; Aig_ObjDisconnect( p, pObjNew ); Aig_ObjConnect( p, pObjOld, pFanin0, pFanin1 ); // delete the new object Aig_ObjDelete( p, pObjNew ); // update levels if ( p->pFanData ) { pObjOld->Level = LevelOld; Aig_ManUpdateLevel( p, pObjOld ); } if ( fUpdateLevel ) { Aig_ObjClearReverseLevel( p, pObjOld ); Aig_ManUpdateReverseLevel( p, pObjOld ); } } p->nObjs[pObjOld->Type]++; // store buffers if fanout is allocated if ( p->pFanData && Aig_ObjIsBuf(pObjOld) ) { Vec_PtrPush( p->vBufs, pObjOld ); p->nBufMax = AIG_MAX( p->nBufMax, Vec_PtrSize(p->vBufs) ); Aig_ManPropagateBuffers( p, fNodesOnly, fUpdateLevel ); } }
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 [Computes the max number of levels in the manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_ManCountLevels( Aig_Man_t * p ) { Vec_Ptr_t * vNodes; Aig_Obj_t * pObj; int i, LevelsMax, Level0, Level1; // initialize the levels Aig_ManConst1(p)->pData = NULL; Aig_ManForEachPi( p, pObj, i ) pObj->pData = NULL; // compute levels in a DFS order vNodes = Aig_ManDfs( p ); Vec_PtrForEachEntry( vNodes, pObj, i ) { Level0 = (int)Aig_ObjFanin0(pObj)->pData; Level1 = (int)Aig_ObjFanin1(pObj)->pData; pObj->pData = (void *)(1 + Aig_ObjIsExor(pObj) + AIG_MAX(Level0, Level1)); }
/**Function************************************************************* Synopsis [Expands the cut by adding the most closely related node.] Description [Returns 1 if the cut exists.] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_NodeMffsExtendCut( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vResult ) { Aig_Obj_t * pObj, * pLeafBest; int i, LevelMax, ConeSize1, ConeSize2, ConeCur1, ConeCur2, ConeBest; // dereference the current cut LevelMax = 0; Vec_PtrForEachEntry( vLeaves, pObj, i ) LevelMax = AIG_MAX( LevelMax, (int)pObj->Level ); if ( LevelMax == 0 ) return 0; // dereference the cut ConeSize1 = Aig_NodeDeref_rec( pNode, 0 ); // try expanding each node in the boundary ConeBest = AIG_INFINITY; pLeafBest = NULL; Vec_PtrForEachEntry( vLeaves, pObj, i ) { if ( (int)pObj->Level != LevelMax ) continue; ConeCur1 = Aig_NodeDeref_rec( pObj, 0 ); if ( ConeBest > ConeCur1 ) { ConeBest = ConeCur1; pLeafBest = pObj; } ConeCur2 = Aig_NodeRef_rec( pObj, 0 ); assert( ConeCur1 == ConeCur2 ); } assert( pLeafBest != NULL ); assert( Aig_ObjIsNode(pLeafBest) ); // deref the best leaf ConeCur1 = Aig_NodeDeref_rec( pLeafBest, 0 ); // collect the cut nodes Vec_PtrClear( vResult ); Aig_ManIncrementTravId( p ); Aig_NodeMffsSupp_rec( p, pNode, 0, vResult, 1, pLeafBest ); // ref the nodes ConeCur2 = Aig_NodeRef_rec( pLeafBest, 0 ); assert( ConeCur1 == ConeCur2 ); // ref the original node ConeSize2 = Aig_NodeRef_rec( pNode, 0 ); assert( ConeSize1 == ConeSize2 ); return 1; }
/**Function************************************************************* Synopsis [Sets variable activities in the cone.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_SetActivityFactors( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) { int clk, LevelMin, LevelMax; assert( pOld || pNew ); clk = clock(); // reset the active variables veci_resize(&p->pSat->act_vars, 0); // prepare for traversal Aig_ManIncrementTravId( p->pManFraig ); // determine the min and max level to visit assert( p->pPars->dActConeRatio > 0 && p->pPars->dActConeRatio < 1 ); LevelMax = AIG_MAX( (pNew ? pNew->Level : 0), (pOld ? pOld->Level : 0) ); LevelMin = (int)(LevelMax * (1.0 - p->pPars->dActConeRatio)); // traverse if ( pOld && !Aig_ObjIsConst1(pOld) ) Fra_SetActivityFactors_rec( p, pOld, LevelMin, LevelMax ); if ( pNew && !Aig_ObjIsConst1(pNew) ) Fra_SetActivityFactors_rec( p, pNew, LevelMin, LevelMax ); //Fra_PrintActivity( p ); p->timeTrav += clock() - clk; return 1; }
Aig_ManConst1(p)->pData = NULL; Aig_ManForEachPi( p, pObj, i ) pObj->pData = NULL; // compute levels in a DFS order vNodes = Aig_ManDfs( p ); Vec_PtrForEachEntry( vNodes, pObj, i ) { Level0 = (int)Aig_ObjFanin0(pObj)->pData; Level1 = (int)Aig_ObjFanin1(pObj)->pData; pObj->pData = (void *)(1 + Aig_ObjIsExor(pObj) + AIG_MAX(Level0, Level1)); } Vec_PtrFree( vNodes ); // get levels of the POs LevelsMax = 0; Aig_ManForEachPo( p, pObj, i ) LevelsMax = AIG_MAX( LevelsMax, (int)Aig_ObjFanin0(pObj)->pData ); return LevelsMax; } /**Function************************************************************* Synopsis [Counts the number of AIG nodes rooted at this cone.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ConeMark_rec( Aig_Obj_t * pObj )