Commit 80d2eef7 by Alan Mishchenko

Adding switch to control area/delay quality tradeoff in 'amap'.

parent 22ada3b2
...@@ -14015,7 +14015,7 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -14015,7 +14015,7 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv )
fSweep = 0; fSweep = 0;
Amap_ManSetDefaultParams( pPars ); Amap_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "FAEmxisvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "FAEQmxisvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -14052,6 +14052,17 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -14052,6 +14052,17 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->fEpsilon < 0.0 || pPars->fEpsilon > 1.0 ) if ( pPars->fEpsilon < 0.0 || pPars->fEpsilon > 1.0 )
goto usage; goto usage;
break; 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': case 'm':
pPars->fUseMuxes ^= 1; pPars->fUseMuxes ^= 1;
break; break;
...@@ -14131,11 +14142,12 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -14131,11 +14142,12 @@ int Abc_CommandAmap( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: 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 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-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-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-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-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-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" ); Abc_Print( -2, "\t-i : toggles assuming inverters are free [default = %s]\n", pPars->fFreeInvs? "yes": "no" );
...@@ -50,6 +50,7 @@ struct Amap_Par_t_ ...@@ -50,6 +50,7 @@ struct Amap_Par_t_
int fUseXors; // enables the use of XORs int fUseXors; // enables the use of XORs
int fFreeInvs; // assume inverters are free (area = 0) int fFreeInvs; // assume inverters are free (area = 0)
float fEpsilon; // used to compare floating point numbers float fEpsilon; // used to compare floating point numbers
float fADratio; // ratio of area/delay improvement
int fVerbose; // verbosity flag int fVerbose; // verbosity flag
}; };
......
...@@ -218,7 +218,28 @@ int Amap_ManCountInverters( Amap_Man_t * p ) ...@@ -218,7 +218,28 @@ int Amap_ManCountInverters( Amap_Man_t * p )
SeeAlso [] 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 // compare area flows
if ( pM0->Area < pM1->Area - p->pPars->fEpsilon ) 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 ...@@ -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 ) 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_Cut_t * pCut;
Amap_Set_t * pSet; Amap_Set_t * pSet;
Amap_Nod_t * pNod; Amap_Nod_t * pNod;
int i; int i;
if ( fRefs ) if ( fRefs )
pNode->EstRefs = (float)((2.0 * pNode->EstRefs + Amap_ObjRefsTotal(pNode)) / 3.0); pNode->EstRefs = (float)((2.0 * pNode->EstRefs + Amap_ObjRefsTotal(pNode)) / 3.0);
else else
pNode->EstRefs = (float)pNode->nRefs; pNode->EstRefs = (float)pNode->nRefs;
if ( fRefs && Amap_ObjRefsTotal(pNode) > 0 ) if ( fRefs && Amap_ObjRefsTotal(pNode) > 0 )
Amap_CutAreaDeref( p, &pNode->Best ); 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 ) Amap_NodeForEachCut( pNode, pCut, i )
{ {
if ( pCut->iMat == 0 ) if ( pCut->iMat == 0 )
...@@ -457,10 +487,52 @@ void Amap_ManMatchNode( Amap_Man_t * p, Amap_Obj_t * pNode, int fFlow, int fRefs ...@@ -457,10 +487,52 @@ void Amap_ManMatchNode( Amap_Man_t * p, Amap_Obj_t * pNode, int fFlow, int fRefs
Amap_ManMatchGetFlows( p, pMThis ); Amap_ManMatchGetFlows( p, pMThis );
else else
Amap_ManMatchGetExacts( p, pNode, pMThis ); Amap_ManMatchGetExacts( p, pNode, pMThis );
if ( pMBest->pCut == NULL || Amap_CutCompare(p, pMBest, pMThis) == 1 ) if ( pMBestD->pCut == NULL || Amap_CutCompareDelay(p, pMBestD, pMThis) == 1 )
*pMBest = *pMThis; *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->fPolar = pMBest->pCut->fInv ^ pMBest->pSet->fInv;
pNode->Best = *pMBest; pNode->Best = *pMBest;
pNode->Best.pCut = Amap_ManDupCut( p, pNode->Best.pCut ); pNode->Best.pCut = Amap_ManDupCut( p, pNode->Best.pCut );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment