/**Function************************************************************* Synopsis [Transfers the arrival times from the best cuts to the node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_NodeTransferArrivalTimes( Map_Man_t * p, Map_Node_t * pNode ) { // if both phases are available, set their arrival times if ( pNode->pCutBest[0] && pNode->pCutBest[1] ) { pNode->tArrival[0] = pNode->pCutBest[0]->M[0].tArrive; pNode->tArrival[1] = pNode->pCutBest[1]->M[1].tArrive; } // if only one phase is available, compute the arrival time of other phase else if ( pNode->pCutBest[0] ) { pNode->tArrival[0] = pNode->pCutBest[0]->M[0].tArrive; pNode->tArrival[1].Rise = pNode->tArrival[0].Fall + p->pSuperLib->tDelayInv.Rise; pNode->tArrival[1].Fall = pNode->tArrival[0].Rise + p->pSuperLib->tDelayInv.Fall; pNode->tArrival[1].Worst = MAP_MAX(pNode->tArrival[1].Rise, pNode->tArrival[1].Fall); } else if ( pNode->pCutBest[1] ) { pNode->tArrival[1] = pNode->pCutBest[1]->M[1].tArrive; pNode->tArrival[0].Rise = pNode->tArrival[1].Fall + p->pSuperLib->tDelayInv.Rise; pNode->tArrival[0].Fall = pNode->tArrival[1].Rise + p->pSuperLib->tDelayInv.Fall; pNode->tArrival[0].Worst = MAP_MAX(pNode->tArrival[0].Rise, pNode->tArrival[0].Fall); } else { assert( 0 ); } assert( pNode->tArrival[0].Rise < pNode->tRequired[0].Rise + p->fEpsilon ); assert( pNode->tArrival[0].Fall < pNode->tRequired[0].Fall + p->fEpsilon ); assert( pNode->tArrival[1].Rise < pNode->tRequired[1].Rise + p->fEpsilon ); assert( pNode->tArrival[1].Fall < pNode->tRequired[1].Fall + p->fEpsilon ); }
/**Function************************************************************* Synopsis [Analyses choice nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Map_MappingUpdateLevel_rec( Map_Man_t * pMan, Map_Node_t * pNode, int fMaximum ) { Map_Node_t * pTemp; int Level1, Level2, LevelE; assert( !Map_IsComplement(pNode) ); if ( !Map_NodeIsAnd(pNode) ) return pNode->Level; // skip the visited node if ( pNode->TravId == pMan->nTravIds ) return pNode->Level; pNode->TravId = pMan->nTravIds; // compute levels of the children nodes Level1 = Map_MappingUpdateLevel_rec( pMan, Map_Regular(pNode->p1), fMaximum ); Level2 = Map_MappingUpdateLevel_rec( pMan, Map_Regular(pNode->p2), fMaximum ); pNode->Level = 1 + MAP_MAX( Level1, Level2 ); if ( pNode->pNextE ) { LevelE = Map_MappingUpdateLevel_rec( pMan, pNode->pNextE, fMaximum ); if ( fMaximum ) { if ( pNode->Level < (unsigned)LevelE ) pNode->Level = LevelE; } else { if ( pNode->Level > (unsigned)LevelE ) pNode->Level = LevelE; } // set the level of all equivalent nodes to be the same minimum if ( pNode->pRepr == NULL ) // the primary node for ( pTemp = pNode->pNextE; pTemp; pTemp = pTemp->pNextE ) pTemp->Level = pNode->Level; } return pNode->Level; }
/**function************************************************************* synopsis [Computes the exact area associated with the cut.] description [] sideeffects [] seealso [] ***********************************************************************/ float Map_TimeMatchWithInverter( Map_Man_t * p, Map_Match_t * pMatch ) { Map_Time_t tArrInv; tArrInv.Fall = pMatch->tArrive.Rise + p->pSuperLib->tDelayInv.Fall; tArrInv.Rise = pMatch->tArrive.Fall + p->pSuperLib->tDelayInv.Rise; tArrInv.Worst = MAP_MAX( tArrInv.Rise, tArrInv.Fall ); return tArrInv.Worst; }
float Map_MatchComputeReqTimes( Map_Cut_t * pCut, int fPhase, Map_Time_t * ptArrRes ) { Map_Time_t * ptArrIn; Map_Super_t * pSuper; unsigned uPhaseTot; int fPinPhase, i; float tDelay; // get the supergate and the phase pSuper = pCut->M[fPhase].pSuperBest; uPhaseTot = pCut->M[fPhase].uPhaseBest; // propagate the arrival times ptArrRes->Rise = ptArrRes->Fall = -MAP_FLOAT_LARGE; for ( i = 0; i < pCut->nLeaves; i++ ) { // get the phase of the given pin fPinPhase = ((uPhaseTot & (1 << i)) == 0); ptArrIn = pCut->ppLeaves[i]->tRequired + fPinPhase; // assert( ptArrIn->Worst < MAP_FLOAT_LARGE ); // get the rise of the output due to rise of the inputs if ( pSuper->tDelaysR[i].Rise > 0 ) { tDelay = ptArrIn->Rise + pSuper->tDelaysR[i].Rise; if ( ptArrRes->Rise < tDelay ) ptArrRes->Rise = tDelay; } // get the rise of the output due to fall of the inputs if ( pSuper->tDelaysR[i].Fall > 0 ) { tDelay = ptArrIn->Fall + pSuper->tDelaysR[i].Fall; if ( ptArrRes->Rise < tDelay ) ptArrRes->Rise = tDelay; } // get the fall of the output due to rise of the inputs if ( pSuper->tDelaysF[i].Rise > 0 ) { tDelay = ptArrIn->Rise + pSuper->tDelaysF[i].Rise; if ( ptArrRes->Fall < tDelay ) ptArrRes->Fall = tDelay; } // get the fall of the output due to fall of the inputs if ( pSuper->tDelaysF[i].Fall > 0 ) { tDelay = ptArrIn->Fall + pSuper->tDelaysF[i].Fall; if ( ptArrRes->Fall < tDelay ) ptArrRes->Fall = tDelay; } } // return the worst-case of rise/fall arrival times return MAP_MAX(ptArrRes->Rise, ptArrRes->Fall); }
/**Function************************************************************* Synopsis [Sets the PI arrival times.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Map_MappingSetPiArrivalTimes( Map_Man_t * p ) { Map_Node_t * pNode; int i; for ( i = 0; i < p->nInputs; i++ ) { pNode = p->pInputs[i]; // set the arrival time of the positive phase pNode->tArrival[1] = p->pInputArrivals[i]; // set the arrival time of the negative phase pNode->tArrival[0].Rise = pNode->tArrival[1].Fall + p->pSuperLib->tDelayInv.Rise; pNode->tArrival[0].Fall = pNode->tArrival[1].Rise + p->pSuperLib->tDelayInv.Fall; pNode->tArrival[0].Worst = MAP_MAX(pNode->tArrival[0].Rise, pNode->tArrival[0].Fall); } }
/**Function************************************************************* Synopsis [Creates a new node.] Description [This procedure should be called to create the constant node and the PI nodes first.] SideEffects [] SeeAlso [] ***********************************************************************/ Map_Node_t * Map_NodeCreate( Map_Man_t * p, Map_Node_t * p1, Map_Node_t * p2 ) { Map_Node_t * pNode; // create the node pNode = (Map_Node_t *)Extra_MmFixedEntryFetch( p->mmNodes ); memset( pNode, 0, sizeof(Map_Node_t) ); pNode->tRequired[0].Rise = pNode->tRequired[0].Fall = pNode->tRequired[0].Worst = MAP_FLOAT_LARGE; pNode->tRequired[1].Rise = pNode->tRequired[1].Fall = pNode->tRequired[1].Worst = MAP_FLOAT_LARGE; pNode->p1 = p1; pNode->p2 = p2; pNode->p = p; // set the number of this node pNode->Num = p->nNodes++; // place to store the fanouts // pNode->vFanouts = Map_NodeVecAlloc( 5 ); // store this node in the internal array if ( pNode->Num >= 0 ) Map_NodeVecPush( p->vMapObjs, pNode ); else pNode->fInv = 1; // set the level of this node if ( p1 ) { #ifdef MAP_ALLOCATE_FANOUT // create the fanout info Map_NodeAddFaninFanout( Map_Regular(p1), pNode ); if ( p2 ) Map_NodeAddFaninFanout( Map_Regular(p2), pNode ); #endif if ( p2 ) { pNode->Level = 1 + MAP_MAX(Map_Regular(pNode->p1)->Level, Map_Regular(pNode->p2)->Level); pNode->fInv = Map_NodeIsSimComplement(p1) & Map_NodeIsSimComplement(p2); } else { pNode->Level = Map_Regular(pNode->p1)->Level; pNode->fInv = Map_NodeIsSimComplement(p1); } } // reference the inputs (will be used to compute the number of fanouts) if ( p1 ) Map_NodeRef(p1); if ( p2 ) Map_NodeRef(p2); pNode->nRefEst[0] = pNode->nRefEst[1] = -1; return pNode; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Computes the maximum arrival times.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ float Map_TimeComputeArrivalMax( Map_Man_t * p ) { float tReqMax, tReq; int i, fPhase; // get the critical PO arrival time tReqMax = -MAP_FLOAT_LARGE; for ( i = 0; i < p->nOutputs; i++ ) { if ( Map_NodeIsConst(p->pOutputs[i]) ) continue; fPhase = !Map_IsComplement(p->pOutputs[i]); tReq = Map_Regular(p->pOutputs[i])->tArrival[fPhase].Worst; tReqMax = MAP_MAX( tReqMax, tReq ); } return tReqMax; }
/**Function************************************************************* Synopsis [Computes the arrival times of the cut.] Description [Computes the arrival times of the cut if it is implemented using the given supergate with the given phase. Uses the constraint-type specification of rise/fall arrival times.] SideEffects [] SeeAlso [] ***********************************************************************/ float Map_TimeCutComputeArrival( Map_Node_t * pNode, Map_Cut_t * pCut, int fPhase, float tWorstLimit ) { Map_Match_t * pM = pCut->M + fPhase; Map_Super_t * pSuper = pM->pSuperBest; unsigned uPhaseTot = pM->uPhaseBest; Map_Time_t * ptArrRes = &pM->tArrive; Map_Time_t * ptArrIn; int fPinPhase; float tDelay, tExtra; int i; tExtra = pNode->p->pNodeDelays ? pNode->p->pNodeDelays[pNode->Num] : 0; ptArrRes->Rise = ptArrRes->Fall = 0.0; ptArrRes->Worst = MAP_FLOAT_LARGE; for ( i = pCut->nLeaves - 1; i >= 0; i-- ) { // get the phase of the given pin fPinPhase = ((uPhaseTot & (1 << i)) == 0); ptArrIn = pCut->ppLeaves[i]->tArrival + fPinPhase; // get the rise of the output due to rise of the inputs if ( pSuper->tDelaysR[i].Rise > 0 ) { tDelay = ptArrIn->Rise + pSuper->tDelaysR[i].Rise + tExtra; if ( tDelay > tWorstLimit ) return MAP_FLOAT_LARGE; if ( ptArrRes->Rise < tDelay ) ptArrRes->Rise = tDelay; } // get the rise of the output due to fall of the inputs if ( pSuper->tDelaysR[i].Fall > 0 ) { tDelay = ptArrIn->Fall + pSuper->tDelaysR[i].Fall + tExtra; if ( tDelay > tWorstLimit ) return MAP_FLOAT_LARGE; if ( ptArrRes->Rise < tDelay ) ptArrRes->Rise = tDelay; } // get the fall of the output due to rise of the inputs if ( pSuper->tDelaysF[i].Rise > 0 ) { tDelay = ptArrIn->Rise + pSuper->tDelaysF[i].Rise + tExtra; if ( tDelay > tWorstLimit ) return MAP_FLOAT_LARGE; if ( ptArrRes->Fall < tDelay ) ptArrRes->Fall = tDelay; } // get the fall of the output due to fall of the inputs if ( pSuper->tDelaysF[i].Fall > 0 ) { tDelay = ptArrIn->Fall + pSuper->tDelaysF[i].Fall + tExtra; if ( tDelay > tWorstLimit ) return MAP_FLOAT_LARGE; if ( ptArrRes->Fall < tDelay ) ptArrRes->Fall = tDelay; } } // return the worst-case of rise/fall arrival times ptArrRes->Worst = MAP_MAX(ptArrRes->Rise, ptArrRes->Fall); return ptArrRes->Worst; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Reads in the supergate library and prepares it for use.] Description [The supergates library comes in a .super file. This file contains descriptions of supergates along with some relevant information. This procedure reads the supergate file, canonicizes the supergates, and constructs an additional lookup table, which can be used to map truth tables of the cuts into the pair (phase, supergate). The phase indicates how the current truth table should be phase assigned to match the canonical form of the supergate. The resulting phase is the bitwise EXOR of the phase needed to canonicize the supergate and the phase needed to transform the truth table into its canonical form.] SideEffects [] SeeAlso [] ***********************************************************************/ Map_SuperLib_t * Map_SuperLibCreate( char * pFileName, char * pExcludeFile, int fAlgorithm, int fVerbose ) { Map_SuperLib_t * p; clock_t clk; // start the supergate library p = ABC_ALLOC( Map_SuperLib_t, 1 ); memset( p, 0, sizeof(Map_SuperLib_t) ); p->pName = pFileName; p->fVerbose = fVerbose; p->mmSupers = Extra_MmFixedStart( sizeof(Map_Super_t) ); p->mmEntries = Extra_MmFixedStart( sizeof(Map_HashEntry_t) ); p->mmForms = Extra_MmFlexStart(); Map_MappingSetupTruthTables( p->uTruths ); // start the hash table p->tTableC = Map_SuperTableCreate( p ); p->tTable = Map_SuperTableCreate( p ); // read the supergate library from file clk = clock(); if ( fAlgorithm ) { if ( !Map_LibraryReadTree( p, pFileName, pExcludeFile ) ) { Map_SuperLibFree( p ); return NULL; } } else { if ( pExcludeFile != 0 ) { Map_SuperLibFree( p ); printf ("Error: Exclude file support not present for old format. Stop.\n"); return NULL; } if ( !Map_LibraryRead( p, pFileName ) ) { Map_SuperLibFree( p ); return NULL; } } assert( p->nVarsMax > 0 ); // report the stats if ( fVerbose ) { printf( "Loaded %d unique %d-input supergates from \"%s\". ", p->nSupersReal, p->nVarsMax, pFileName ); ABC_PRT( "Time", clock() - clk ); } // assign the interver parameters p->pGateInv = Mio_LibraryReadInv( p->pGenlib ); p->tDelayInv.Rise = Mio_LibraryReadDelayInvRise( p->pGenlib ); p->tDelayInv.Fall = Mio_LibraryReadDelayInvFall( p->pGenlib ); p->tDelayInv.Worst = MAP_MAX( p->tDelayInv.Rise, p->tDelayInv.Fall ); p->AreaInv = Mio_LibraryReadAreaInv( p->pGenlib ); p->AreaBuf = Mio_LibraryReadAreaBuf( p->pGenlib ); // assign the interver supergate p->pSuperInv = (Map_Super_t *)Extra_MmFixedEntryFetch( p->mmSupers ); memset( p->pSuperInv, 0, sizeof(Map_Super_t) ); p->pSuperInv->Num = -1; p->pSuperInv->nGates = 1; p->pSuperInv->nFanins = 1; p->pSuperInv->nFanLimit = 10; p->pSuperInv->pFanins[0] = p->ppSupers[0]; p->pSuperInv->pRoot = p->pGateInv; p->pSuperInv->Area = p->AreaInv; p->pSuperInv->tDelayMax = p->tDelayInv; p->pSuperInv->tDelaysR[0].Rise = MAP_NO_VAR; p->pSuperInv->tDelaysR[0].Fall = p->tDelayInv.Rise; p->pSuperInv->tDelaysF[0].Rise = p->tDelayInv.Fall; p->pSuperInv->tDelaysF[0].Fall = MAP_NO_VAR; return p; }