diff options
Diffstat (limited to 'src/map/if/ifMap.c')
-rw-r--r-- | src/map/if/ifMap.c | 334 |
1 files changed, 262 insertions, 72 deletions
diff --git a/src/map/if/ifMap.c b/src/map/if/ifMap.c index 5f2c4133..0b505062 100644 --- a/src/map/if/ifMap.c +++ b/src/map/if/ifMap.c @@ -24,13 +24,69 @@ /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +/* + Ideas to try: + - reverse order of area recovery + - ordering of the outputs by size + - merging Delay, Delay2, and Area + - expand/reduce area recovery + +*/ + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Prepares the object for FPGA mapping.] + Synopsis [Returns 1 if pDom is contained in pCut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut ) +{ + int i, k; + for ( i = 0; i < (int)pDom->nLeaves; i++ ) + { + for ( k = 0; k < (int)pCut->nLeaves; k++ ) + if ( pDom->pLeaves[i] == pCut->pLeaves[k] ) + break; + if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut + return 0; + } + // every node in pDom is contained in pCut + return 1; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if pDom is equal to pCut.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int If_CutCheckEquality( If_Cut_t * pDom, If_Cut_t * pCut ) +{ + int i; + if ( (int)pDom->nLeaves != (int)pCut->nLeaves ) + return 0; + for ( i = 0; i < (int)pDom->nLeaves; i++ ) + if ( pDom->pLeaves[i] != pCut->pLeaves[i] ) + return 0; + return 1; +} +/**Function************************************************************* + + Synopsis [Returns 1 if the cut is contained.] Description [] @@ -39,8 +95,39 @@ SeeAlso [] ***********************************************************************/ -int If_CutMerge( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit ) +int If_CutFilter( If_Man_t * p, If_Cut_t * pCut ) { + If_Cut_t * pTemp; + int i; + for ( i = 0; i < p->nCuts; i++ ) + { + pTemp = p->ppCuts[i]; + if ( pTemp->nLeaves > pCut->nLeaves ) + continue; + // skip the non-contained cuts +// if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign ) +// continue; + // check containment seriously + if ( If_CutCheckDominance( pTemp, pCut ) ) +// if ( If_CutCheckEquality( pTemp, pCut ) ) + return 1; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Prepares the object for FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int If_CutMergeOrdered( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit ) +{ int i, k, c; assert( pC0->nLeaves >= pC1->nLeaves ); // the case of the largest cut sizes @@ -125,6 +212,33 @@ int If_CutMerge( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC, int nLimit ) SeeAlso [] ***********************************************************************/ +static inline int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut, int nLimit ) +{ + // merge the nodes + if ( pCut0->nLeaves < pCut1->nLeaves ) + { + if ( !If_CutMergeOrdered( pCut1, pCut0, pCut, nLimit ) ) + return 0; + } + else + { + if ( !If_CutMergeOrdered( pCut0, pCut1, pCut, nLimit ) ) + return 0; + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Prepares the object for FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int If_CutCompareDelay( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) { If_Cut_t * pC0 = *ppC0; @@ -137,9 +251,39 @@ int If_CutCompareDelay( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) return -1; if ( pC0->nLeaves > pC1->nLeaves ) return 1; - if ( pC0->Flow < pC1->Flow ) + if ( pC0->Area < pC1->Area ) return -1; - if ( pC0->Flow > pC1->Flow ) + if ( pC0->Area > pC1->Area ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [Prepares the object for FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int If_CutCompareDelayOld( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) +{ + If_Cut_t * pC0 = *ppC0; + If_Cut_t * pC1 = *ppC1; + if ( pC0->Delay < pC1->Delay ) + return -1; + if ( pC0->Delay > pC1->Delay ) + return 1; + if ( pC0->Area < pC1->Area ) + return -1; + if ( pC0->Area > pC1->Area ) + return 1; + if ( pC0->nLeaves < pC1->nLeaves ) + return -1; + if ( pC0->nLeaves > pC1->nLeaves ) return 1; return 0; } @@ -159,9 +303,9 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) { If_Cut_t * pC0 = *ppC0; If_Cut_t * pC1 = *ppC1; - if ( pC0->Flow < pC1->Flow ) + if ( pC0->Area < pC1->Area ) return -1; - if ( pC0->Flow > pC1->Flow ) + if ( pC0->Area > pC1->Area ) return 1; if ( pC0->nLeaves < pC1->nLeaves ) return -1; @@ -176,6 +320,28 @@ int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) /**Function************************************************************* + Synopsis [Sorts the cuts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void If_ManSortCuts( If_Man_t * p, int Mode ) +{ + // sort the cuts + if ( Mode || p->pPars->fArea ) // area + qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea ); + else if ( p->pPars->fFancy ) + qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelayOld ); + else + qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay ); +} + +/**Function************************************************************* + Synopsis [Computes delay.] Description [] @@ -190,6 +356,7 @@ float If_CutDelay( If_Man_t * p, If_Cut_t * pCut ) If_Obj_t * pLeaf; float Delay; int i; + assert( pCut->nLeaves > 1 ); Delay = -IF_FLOAT_LARGE; If_CutForEachLeaf( p, pCut, pLeaf, i ) Delay = IF_MAX( Delay, If_ObjCutBest(pLeaf)->Delay ); @@ -212,9 +379,18 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut ) If_Obj_t * pLeaf; float Flow; int i; + assert( pCut->nLeaves > 1 ); Flow = If_CutLutArea(p, pCut); If_CutForEachLeaf( p, pCut, pLeaf, i ) - Flow += If_ObjCutBest(pLeaf)->Flow / pLeaf->EstRefs; + { + if ( pLeaf->nRefs == 0 ) + Flow += If_ObjCutBest(pLeaf)->Area; + else + { + assert( pLeaf->EstRefs > p->fEpsilon ); + Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs; + } + } return Flow; } @@ -229,15 +405,19 @@ float If_CutFlow( If_Man_t * p, If_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -float If_CutArea1( If_Man_t * p, If_Cut_t * pCut ) +float If_CutRef( If_Man_t * p, If_Cut_t * pCut, int nLevels ) { If_Obj_t * pLeaf; float Area; int i; Area = If_CutLutArea(p, pCut); If_CutForEachLeaf( p, pCut, pLeaf, i ) - if ( pLeaf->nRefs == 0 ) - Area += If_CutLutArea(p, If_ObjCutBest(pLeaf)); + { + assert( pLeaf->nRefs >= 0 ); + if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 ) + continue; + Area += If_CutRef( p, If_ObjCutBest(pLeaf), nLevels - 1 ); + } return Area; } @@ -252,12 +432,20 @@ float If_CutArea1( If_Man_t * p, If_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -void If_CutRef1( If_Man_t * p, If_Cut_t * pCut ) +float If_CutDeref( If_Man_t * p, If_Cut_t * pCut, int nLevels ) { If_Obj_t * pLeaf; + float Area; int i; + Area = If_CutLutArea(p, pCut); If_CutForEachLeaf( p, pCut, pLeaf, i ) - pLeaf->nRefs++; + { + assert( pLeaf->nRefs > 0 ); + if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 ) + continue; + Area += If_CutDeref( p, If_ObjCutBest(pLeaf), nLevels - 1 ); + } + return Area; } /**Function************************************************************* @@ -271,12 +459,14 @@ void If_CutRef1( If_Man_t * p, If_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -void If_CutDeref1( If_Man_t * p, If_Cut_t * pCut ) +float If_CutArea( If_Man_t * p, If_Cut_t * pCut, int nLevels ) { - If_Obj_t * pLeaf; - int i; - If_CutForEachLeaf( p, pCut, pLeaf, i ) - pLeaf->nRefs--; + float aResult, aResult2; + assert( pCut->nLeaves > 1 ); + aResult2 = If_CutRef( p, pCut, nLevels ); + aResult = If_CutDeref( p, pCut, nLevels ); + assert( aResult == aResult2 ); + return aResult; } /**Function************************************************************* @@ -303,85 +493,85 @@ void If_CutCopy( If_Cut_t * pCutDest, If_Cut_t * pCutSrc ) Synopsis [Finds the best cut.] - Description [] + Description [Mapping modes: delay (0), area flow (1), area (2).] SideEffects [] SeeAlso [] ***********************************************************************/ -void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj ) +void If_ObjPerformMapping( If_Man_t * p, If_Obj_t * pObj, int Mode ) { If_Cut_t * pCut0, * pCut1, * pCut; int i, k; - // create cross-product of the cuts + + // prepare + if ( Mode == 0 ) + pObj->EstRefs = (float)pObj->nRefs; + else if ( Mode == 1 ) + pObj->EstRefs = (float)((2.0 * pObj->EstRefs + pObj->nRefs) / 3.0); + else if ( Mode == 2 && pObj->nRefs > 0 ) + If_CutDeref( p, If_ObjCutBest(pObj), 100 ); + + // recompute the parameters of the best cut p->nCuts = 0; - pCut = p->ppCuts[0]; + p->nCutsMerged++; + if ( Mode ) + { + pCut = If_ObjCutBest(pObj); + pCut->Delay = If_CutDelay( p, pCut ); + assert( pCut->Delay <= pObj->Required + p->fEpsilon ); + pCut->Area = (Mode == 2)? If_CutArea( p, pCut, 100 ) : If_CutFlow( p, pCut ); + // save the best cut from the previous iteration + If_CutCopy( p->ppCuts[p->nCuts++], pCut ); + p->nCutsMerged++; + } + + // generate cuts + pCut = p->ppCuts[p->nCuts]; If_ObjForEachCut( pObj->pFanin0, pCut0, i ) If_ObjForEachCut( pObj->pFanin1, pCut1, k ) { - if ( pCut0->nLeaves < pCut1->nLeaves ) - { - if ( !If_CutMerge( pCut1, pCut0, pCut, p->pPars->nLutSize ) ) - continue; - } - else - { - if ( !If_CutMerge( pCut0, pCut1, pCut, p->pPars->nLutSize ) ) - continue; - } + // prefilter using arrival times + if ( Mode && (pCut0->Delay > pObj->Required + p->fEpsilon || pCut1->Delay > pObj->Required + p->fEpsilon) ) + continue; + // merge the nodes + if ( !If_CutMerge( pCut0, pCut1, pCut, p->pPars->nLutSize ) ) + continue; + // check if this cut is contained in any of the available cuts + if ( If_CutFilter( p, pCut ) ) + continue; + // check if the cut satisfies the required times + pCut->Delay = If_CutDelay( p, pCut ); + if ( Mode && pCut->Delay > pObj->Required + p->fEpsilon ) + continue; // the cuts have been successfully merged pCut->pOne = pCut0; pCut->fCompl0 = pObj->fCompl0; pCut->pTwo = pCut1; pCut->fCompl1 = pObj->fCompl1; // pCut->Phase = ... - pCut->Delay = If_CutDelay( p, pCut ); - pCut->Flow = If_CutFlow( p, pCut ); + pCut->Area = (Mode == 2)? If_CutArea( p, pCut, 100 ) : If_CutFlow( p, pCut ); + p->nCutsMerged++; // prepare room for the next cut pCut = p->ppCuts[++p->nCuts]; } - // sort the cuts - if ( p->pPars->Mode == 1 ) // delay - qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay ); - else - qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea ); + assert( p->nCuts > 0 ); + If_ManSortCuts( p, Mode ); // take the first - pObj->nCuts = IF_MIN( p->nCuts + 1, p->pPars->nCutsMax ); + pObj->nCuts = IF_MIN( p->nCuts + 1, p->nCutsUsed ); If_ObjForEachCutStart( pObj, pCut, i, 1 ) If_CutCopy( pCut, p->ppCuts[i-1] ); pObj->iCut = 1; -} - -/**Function************************************************************* - - Synopsis [Maps the nodes for delay.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int If_ManPerformMapping( If_Man_t * p ) -{ - If_Obj_t * pObj; - float DelayBest; - int i, clk = clock(); - // set arrival times and trivial cuts at const 1 and PIs - If_ManConst1(p)->Cuts[0].Delay = 0.0; - If_ManForEachPi( p, pObj, i ) - pObj->Cuts[0].Delay = p->pPars->pTimesArr[i]; - // set the initial fanout estimates - If_ManForEachObj( p, pObj, i ) - pObj->EstRefs = (float)pObj->nRefs; - // map the internal nodes - If_ManForEachNode( p, pObj, i ) - If_ObjPerformMapping( p, pObj ); - // get the best arrival time of the POs - DelayBest = If_ManDelayMax(p); - printf( "Best delay = %d. ", (int)DelayBest ); - PRT( "Time", clock() - clk ); - return 1; + assert( If_ObjCutBest(pObj)->nLeaves > 1 ); + // assign delay of the trivial cut + If_ObjCutTriv(pObj)->Delay = If_ObjCutBest(pObj)->Delay; +//printf( "%d %d ", pObj->Id, (int)If_ObjCutBest(pObj)->Delay ); +//printf( "%d %d ", pObj->Id, pObj->nCuts ); + // ref the selected cut + if ( Mode == 2 && pObj->nRefs > 0 ) + If_CutRef( p, If_ObjCutBest(pObj), 100 ); + // find the largest cut + if ( p->nCutsMax < pObj->nCuts ) + p->nCutsMax = pObj->nCuts; } //////////////////////////////////////////////////////////////////////// |