diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2014-04-08 19:22:41 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2014-04-08 19:22:41 -0700 |
commit | 80d2eef712472a5e58dd40bc13a2e757a56a0c01 (patch) | |
tree | 59f4fade1395267ad0a64d3d216b5d06cbc35a4e | |
parent | 22ada3b2b7667c376404b4c870307dd9717563b2 (diff) | |
download | abc-80d2eef712472a5e58dd40bc13a2e757a56a0c01.tar.gz abc-80d2eef712472a5e58dd40bc13a2e757a56a0c01.tar.bz2 abc-80d2eef712472a5e58dd40bc13a2e757a56a0c01.zip |
Adding switch to control area/delay quality tradeoff in 'amap'.
-rw-r--r-- | src/base/abci/abc.c | 16 | ||||
-rw-r--r-- | src/map/amap/amap.h | 1 | ||||
-rw-r--r-- | src/map/amap/amapMatch.c | 82 |
3 files changed, 92 insertions, 7 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 3810fdaf..0e1c26f5 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -14015,7 +14015,7 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv ) fSweep = 0; Amap_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "FAEmxisvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "FAEQmxisvh" ) ) != EOF ) { switch ( c ) { @@ -14052,6 +14052,17 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->fEpsilon < 0.0 || pPars->fEpsilon > 1.0 ) goto usage; break; + case 'Q': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-Q\" should be followed by a floating point number.\n" ); + goto usage; + } + pPars->fADratio = (float)atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->fADratio < 0.0 ) + goto usage; + break; case 'm': pPars->fUseMuxes ^= 1; break; @@ -14131,11 +14142,12 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: amap [-FA <num>] [-E <float>] [-mxisvh]\n" ); + Abc_Print( -2, "usage: amap [-FA <num>] [-EQ <float>] [-mxisvh]\n" ); Abc_Print( -2, "\t performs standard cell mapping of the current network\n" ); Abc_Print( -2, "\t-F num : the number of iterations of area flow [default = %d]\n", pPars->nIterFlow ); Abc_Print( -2, "\t-A num : the number of iterations of exact area [default = %d]\n", pPars->nIterArea ); Abc_Print( -2, "\t-E float : sets epsilon used for tie-breaking [default = %f]\n", pPars->fEpsilon ); + Abc_Print( -2, "\t-Q float : area/delay preference ratio [default = %.2f (area-only)] \n", pPars->fEpsilon ); Abc_Print( -2, "\t-m : toggles using MUX matching [default = %s]\n", pPars->fUseMuxes? "yes": "no" ); Abc_Print( -2, "\t-x : toggles using XOR matching [default = %s]\n", pPars->fUseXors? "yes": "no" ); Abc_Print( -2, "\t-i : toggles assuming inverters are free [default = %s]\n", pPars->fFreeInvs? "yes": "no" ); diff --git a/src/map/amap/amap.h b/src/map/amap/amap.h index 03e9ce44..c897331c 100644 --- a/src/map/amap/amap.h +++ b/src/map/amap/amap.h @@ -50,6 +50,7 @@ struct Amap_Par_t_ int fUseXors; // enables the use of XORs int fFreeInvs; // assume inverters are free (area = 0) float fEpsilon; // used to compare floating point numbers + float fADratio; // ratio of area/delay improvement int fVerbose; // verbosity flag }; diff --git a/src/map/amap/amapMatch.c b/src/map/amap/amapMatch.c index 52e80c26..8b08c993 100644 --- a/src/map/amap/amapMatch.c +++ b/src/map/amap/amapMatch.c @@ -218,7 +218,28 @@ int Amap_ManCountInverters( Amap_Man_t * p ) SeeAlso [] ***********************************************************************/ -static inline int Amap_CutCompare( Amap_Man_t * p, Amap_Mat_t * pM0, Amap_Mat_t * pM1 ) +static inline int Amap_CutCompareDelay( Amap_Man_t * p, Amap_Mat_t * pM0, Amap_Mat_t * pM1 ) +{ + // compare delay + if ( pM0->Delay < pM1->Delay - p->pPars->fEpsilon ) + return -1; + if ( pM0->Delay > pM1->Delay + p->pPars->fEpsilon ) + return 1; + + // compare area flows + if ( pM0->Area < pM1->Area - p->pPars->fEpsilon ) + return -1; + if ( pM0->Area > pM1->Area + p->pPars->fEpsilon ) + return 1; + + // compare average fanouts + if ( pM0->AveFan > pM1->AveFan - p->pPars->fEpsilon ) + return -1; + if ( pM0->AveFan < pM1->AveFan + p->pPars->fEpsilon ) + return 1; + return 1; +} +static inline int Amap_CutCompareArea( Amap_Man_t * p, Amap_Mat_t * pM0, Amap_Mat_t * pM1 ) { // compare area flows if ( pM0->Area < pM1->Area - p->pPars->fEpsilon ) @@ -433,18 +454,27 @@ static inline void Amap_ManMatchGetExacts( Amap_Man_t * p, Amap_Obj_t * pNode, A ***********************************************************************/ void Amap_ManMatchNode( Amap_Man_t * p, Amap_Obj_t * pNode, int fFlow, int fRefs ) { - Amap_Mat_t M1 = {0}, M2 = {0}, * pMBest = &M1, * pMThis = &M2; + int fVerbose = 0; //(pNode->Level == 2 || pNode->Level == 4); + int fVeryVerbose = fVerbose; + + Amap_Mat_t MA = {0}, MD = {0}, M = {0}; + Amap_Mat_t * pMBestA = &MA, * pMBestD = &MD, * pMThis = &M, * pMBest; Amap_Cut_t * pCut; Amap_Set_t * pSet; Amap_Nod_t * pNod; int i; + if ( fRefs ) pNode->EstRefs = (float)((2.0 * pNode->EstRefs + Amap_ObjRefsTotal(pNode)) / 3.0); else pNode->EstRefs = (float)pNode->nRefs; if ( fRefs && Amap_ObjRefsTotal(pNode) > 0 ) Amap_CutAreaDeref( p, &pNode->Best ); - pMBest->pCut = NULL; + + if ( fVerbose ) + printf( "\nNode %d (%d)\n", pNode->Id, pNode->Level ); + + pMBestA->pCut = pMBestD->pCut = NULL; Amap_NodeForEachCut( pNode, pCut, i ) { if ( pCut->iMat == 0 ) @@ -457,10 +487,52 @@ void Amap_ManMatchNode( Amap_Man_t * p, Amap_Obj_t * pNode, int fFlow, int fRefs Amap_ManMatchGetFlows( p, pMThis ); else Amap_ManMatchGetExacts( p, pNode, pMThis ); - if ( pMBest->pCut == NULL || Amap_CutCompare(p, pMBest, pMThis) == 1 ) - *pMBest = *pMThis; + if ( pMBestD->pCut == NULL || Amap_CutCompareDelay(p, pMBestD, pMThis) == 1 ) + *pMBestD = *pMThis; + if ( pMBestA->pCut == NULL || Amap_CutCompareArea(p, pMBestA, pMThis) == 1 ) + *pMBestA = *pMThis; + + if ( fVeryVerbose ) + { + printf( "Cut %2d (%d) : ", i, pCut->nFans ); + printf( "Gate %10s ", Amap_LibGate(p->pLib, pMThis->pSet->iGate)->pName ); + printf( "%s ", pMThis->pSet->fInv ? "inv" : " " ); + printf( "Delay %5.2f ", pMThis->Delay ); + printf( "Area %5.2f ", pMThis->Area ); + printf( "\n" ); + } } } + + if ( Abc_AbsFloat(pMBestA->Area - pMBestD->Area) / pMBestD->Area >= p->pPars->fADratio * Abc_AbsFloat(pMBestA->Delay - pMBestD->Delay) / pMBestA->Delay ) + pMBest = pMBestA; + else + pMBest = pMBestD; + + if ( fVerbose ) + { + printf( "BEST MATCHA: " ); + printf( "Gate %10s ", Amap_LibGate(p->pLib, pMBestA->pSet->iGate)->pName ); + printf( "%s ", pMBestA->pSet->fInv ? "inv" : " " ); + printf( "Delay %5.2f ", pMBestA->Delay ); + printf( "Area %5.2f ", pMBestA->Area ); + printf( "\n" ); + + printf( "BEST MATCHD: " ); + printf( "Gate %10s ", Amap_LibGate(p->pLib, pMBestD->pSet->iGate)->pName ); + printf( "%s ", pMBestD->pSet->fInv ? "inv" : " " ); + printf( "Delay %5.2f ", pMBestD->Delay ); + printf( "Area %5.2f ", pMBestD->Area ); + printf( "\n" ); + + printf( "BEST MATCH : " ); + printf( "Gate %10s ", Amap_LibGate(p->pLib, pMBest->pSet->iGate)->pName ); + printf( "%s ", pMBest->pSet->fInv ? "inv" : " " ); + printf( "Delay %5.2f ", pMBest->Delay ); + printf( "Area %5.2f ", pMBest->Area ); + printf( "\n" ); + } + pNode->fPolar = pMBest->pCut->fInv ^ pMBest->pSet->fInv; pNode->Best = *pMBest; pNode->Best.pCut = Amap_ManDupCut( p, pNode->Best.pCut ); |