/**Function************************************************************* Synopsis [Returns the max delay of the POs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float If_ManDelayMax( If_Man_t * p, int fSeq ) { If_Obj_t * pObj; float DelayBest; int i; if ( p->pPars->fLatchPaths && p->pPars->nLatches == 0 ) { Abc_Print( 0, "Delay optimization of latch path is not performed because there is no latches.\n" ); p->pPars->fLatchPaths = 0; } DelayBest = -IF_FLOAT_LARGE; if ( fSeq ) { assert( p->pPars->nLatches > 0 ); If_ManForEachPo( p, pObj, i ) if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) ) DelayBest = If_ObjArrTime(If_ObjFanin0(pObj)); } else if ( p->pPars->fLatchPaths )
/**Function************************************************************* Synopsis [Performs area recovery for each node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ManImproveMark_rec( If_Man_t * p, If_Obj_t * pObj, Vec_Ptr_t * vVisited ) { if ( pObj->fMark ) return; assert( If_ObjIsAnd(pObj) ); If_ManImproveMark_rec( p, If_ObjFanin0(pObj), vVisited ); If_ManImproveMark_rec( p, If_ObjFanin1(pObj), vVisited ); Vec_PtrPush( vVisited, pObj ); pObj->fMark = 1; }
/**Function************************************************************* Synopsis [Derive truth table for each cofactor.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int If_ManCutTruthCheck_rec( If_Obj_t * pObj, word * pTruths ) { word T0, T1; if ( pObj->fMark ) return pTruths[If_ObjId(pObj)]; assert( If_ObjIsAnd(pObj) ); T0 = If_ManCutTruthCheck_rec( If_ObjFanin0(pObj), pTruths ); T1 = If_ManCutTruthCheck_rec( If_ObjFanin1(pObj), pTruths ); T0 = If_ObjFaninC0(pObj) ? ~T0 : T0; T1 = If_ObjFaninC1(pObj) ? ~T1 : T1; return T0 & T1; }
/**Function************************************************************* Synopsis [Returns 1 if the node Leaf is reachable on the path.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int If_ManCutReach_rec( If_Obj_t * pPath, If_Obj_t * pLeaf ) { if ( pPath == pLeaf ) return 1; if ( pPath->fMark ) return 0; assert( If_ObjIsAnd(pPath) ); if ( If_ManCutReach_rec( If_ObjFanin0(pPath), pLeaf ) ) return 1; if ( If_ManCutReach_rec( If_ObjFanin1(pPath), pLeaf ) ) return 1; return 0; }
/**Function************************************************************* Synopsis [Prepares for sequential mapping by linking the latches.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ManPrepareMappingSeq( If_Man_t * p ) { If_Obj_t * pObjLi, * pObjLo; int i; // link the latch outputs (CIs) directly to the drivers of latch inputs (COs) for ( i = 0; i < p->pPars->nLatches; i++ ) { pObjLi = If_ManLi( p, i ); pObjLo = If_ManLo( p, i ); pObjLo->pFanin0 = If_ObjFanin0( pObjLi ); pObjLo->fCompl0 = If_ObjFaninC0( pObjLi ); } }
/**Function************************************************************* Synopsis [Performs one pass of l-value computation over all nodes.] Description [Experimentally it was found that checking POs changes is not enough to detect the convergence of l-values in the network.] SideEffects [] SeeAlso [] ***********************************************************************/ int If_ManPerformMappingRoundSeq( If_Man_t * p, int nIter ) { If_Obj_t * pObj; int i, clk = clock(); int fVeryVerbose = 0; int fChange = 0; if ( nIter == 1 ) { // if some latches depend on PIs, update their values Vec_PtrForEachEntry( If_Obj_t *, p->vLatchOrder, pObj, i ) { If_ObjSetLValue( pObj, If_ObjLValue(If_ObjFanin0(pObj)) - p->Period ); If_ObjSetArrTime( pObj, If_ObjLValue(pObj) ); } }
/**Function************************************************************* Synopsis [Interface with the FPGA mapping package.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ManComputeSwitching( If_Man_t * pIfMan ) { abctime clk = Abc_Clock(); Gia_Man_t * pNew; Vec_Int_t * vCopy; If_Obj_t * pIfObj; int i; assert( pIfMan->vSwitching == NULL ); // create the new manager pNew = Gia_ManStart( If_ManObjNum(pIfMan) ); vCopy = Vec_IntAlloc( If_ManObjNum(pIfMan) ); // constant and inputs Vec_IntPush( vCopy, 1 ); If_ManForEachCi( pIfMan, pIfObj, i ) Vec_IntPush( vCopy, Gia_ManAppendCi(pNew) ); // internal nodes If_ManForEachNode( pIfMan, pIfObj, i ) { int iLit0 = Abc_LitNotCond( Vec_IntEntry(vCopy, If_ObjFanin0(pIfObj)->Id), If_ObjFaninC0(pIfObj) ); int iLit1 = Abc_LitNotCond( Vec_IntEntry(vCopy, If_ObjFanin1(pIfObj)->Id), If_ObjFaninC1(pIfObj) ); Vec_IntPush( vCopy, Gia_ManAppendAnd(pNew, iLit0, iLit1) ); }
if ( If_ObjLValue(pObj) < If_ObjCutBest(pObj)->Delay - p->fEpsilon ) { If_ObjSetLValue( pObj, If_ObjCutBest(pObj)->Delay ); fChange = 1; } //Abc_Print( 1, "%d ", (int)If_ObjLValue(pObj) ); // reset the visit counters assert( pObj->nVisits == 0 ); pObj->nVisits = pObj->nVisitsCopy; } //Abc_Print( 1, "\n" ); // propagate LValues over the registers Vec_PtrForEachEntry( If_Obj_t *, p->vLatchOrder, pObj, i ) { If_ObjSetLValue( pObj, If_ObjLValue(If_ObjFanin0(pObj)) - p->Period ); If_ObjSetArrTime( pObj, If_ObjLValue(pObj) ); } // compute area and delay If_ManMarkMapping( p ); if ( fVeryVerbose ) { p->RequiredGlo = If_ManDelayMax( p, 1 ); // p->AreaGlo = If_ManScanMapping(p); Abc_Print( 1, "S%d: Fi = %6.2f. Del = %6.2f. Area = %8.2f. Cuts = %8d. ", nIter, (float)p->Period, p->RequiredGlo, p->AreaGlo, p->nCutsMerged ); Abc_PrintTime( 1, "T", clock() - clk ); } return fChange; }
// outputs If_ManForEachCo( pIfMan, pIfObj, i ) { int iLit0 = Abc_LitNotCond( Vec_IntEntry(vCopy, If_ObjFanin0(pIfObj)->Id), If_ObjFaninC0(pIfObj) ); Vec_IntPush( vCopy, Gia_ManAppendCo(pNew, iLit0) ); }
Abc_Print( 0, "Delay optimization of latch path is not performed because there is no latches.\n" ); p->pPars->fLatchPaths = 0; } DelayBest = -IF_FLOAT_LARGE; if ( fSeq ) { assert( p->pPars->nLatches > 0 ); If_ManForEachPo( p, pObj, i ) if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) ) DelayBest = If_ObjArrTime(If_ObjFanin0(pObj)); } else if ( p->pPars->fLatchPaths ) { If_ManForEachLatchInput( p, pObj, i ) if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) ) DelayBest = If_ObjArrTime(If_ObjFanin0(pObj)); } else { If_ManForEachCo( p, pObj, i ) if ( DelayBest < If_ObjArrTime(If_ObjFanin0(pObj)) ) DelayBest = If_ObjArrTime(If_ObjFanin0(pObj)); } return DelayBest; } /**Function************************************************************* Synopsis [Computes the required times of all nodes.] Description []