mirror of https://github.com/YosysHQ/abc.git
Adding support for delay/area tradeoff.
This commit is contained in:
parent
8dd31fb4a9
commit
87f6828d50
|
|
@ -5206,7 +5206,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
// set defaults
|
||||
Sfm_ParSetDefault3( pPars );
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "IOVFKLHRMCNPWDarmzoespdlvwh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "IOVFKLHRMCNPWDEarmzoespdlvwh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -5367,6 +5367,17 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pPars->DeltaCrit < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'E':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-E\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
pPars->DelAreaRatio = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( pPars->DelAreaRatio < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'a':
|
||||
pPars->fArea ^= 1;
|
||||
break;
|
||||
|
|
@ -5424,7 +5435,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: mfs3 [-IOVFKLHRMCNPWD <num>] [-armzespdlvwh]\n" );
|
||||
Abc_Print( -2, "usage: mfs3 [-IOVFKLHRMCNPWDE <num>] [-armzespdlvwh]\n" );
|
||||
Abc_Print( -2, "\t performs don't-care-based optimization of mapped networks\n" );
|
||||
Abc_Print( -2, "\t-I <num> : the number of levels in the TFI cone (1 <= num) [default = %d]\n", pPars->nTfiLevMax );
|
||||
Abc_Print( -2, "\t-O <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevMax );
|
||||
|
|
@ -5440,6 +5451,7 @@ usage:
|
|||
Abc_Print( -2, "\t-P <num> : one particular node to try (0 = none) [default = %d]\n", pPars->iNodeOne );
|
||||
Abc_Print( -2, "\t-W <num> : size of timing window in percents (0 <= num <= 100) [default = %d]\n", pPars->nTimeWin );
|
||||
Abc_Print( -2, "\t-D <num> : size of critical-timing delay-delta (in picoseconds) [default = %d]\n", pPars->DeltaCrit );
|
||||
Abc_Print( -2, "\t-E <num> : delay-area tradeoff (in picoseconds per area-unit) [default = %d]\n", pPars->DelAreaRatio );
|
||||
Abc_Print( -2, "\t-a : toggle area minimization [default = %s]\n", pPars->fArea? "yes": "no" );
|
||||
Abc_Print( -2, "\t-r : toggle using reverse topo order for area minimization [default = %s]\n", pPars->fAreaRev? "yes": "no" );
|
||||
Abc_Print( -2, "\t-m : toggle detecting multi-input AND/OR gates [default = %s]\n", pPars->fUseAndOr? "yes": "no" );
|
||||
|
|
|
|||
|
|
@ -977,7 +977,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pPars->fSizeOnly = 0;
|
||||
pPars->fAddBufs = 1;
|
||||
pPars->fBufPis = 0;
|
||||
pPars->fUseWireLoads = 1;
|
||||
pPars->fUseWireLoads = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
|
|
@ -1384,7 +1384,7 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
pPars->BuffTreeEst = 0;
|
||||
pPars->BypassFreq = 0;
|
||||
pPars->fUseDept = 1;
|
||||
pPars->fUseWireLoads = 1;
|
||||
pPars->fUseWireLoads = 0;
|
||||
pPars->fDumpStats = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
|
|
@ -1594,7 +1594,7 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
pPars->TimeOut = 0;
|
||||
pPars->BuffTreeEst = 0;
|
||||
pPars->fUseDept = 1;
|
||||
pPars->fUseWireLoads = 1;
|
||||
pPars->fUseWireLoads = 0;
|
||||
pPars->fDumpStats = 0;
|
||||
pPars->fVerbose = 0;
|
||||
pPars->fVeryVerbose = 0;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ struct Sfm_Par_t_
|
|||
int nFirstFixed; // the number of first nodes to be treated as fixed
|
||||
int nTimeWin; // the size of timing window in percents
|
||||
int DeltaCrit; // delay delta in picoseconds
|
||||
int DelAreaRatio; // delay/area tradeoff (how many ps we trade for a unit of area)
|
||||
int fRrOnly; // perform redundance removal
|
||||
int fArea; // performs optimization for area
|
||||
int fAreaRev; // performs optimization for area in reverse order
|
||||
|
|
|
|||
|
|
@ -91,9 +91,12 @@ struct Sfm_Dec_t_
|
|||
word * pTtElems[SFM_SUPP_MAX];
|
||||
word * pDivWords[SFM_SUPP_MAX];
|
||||
// temporary
|
||||
Vec_Int_t vTemp;
|
||||
Vec_Int_t vTemp2;
|
||||
Vec_Int_t vTemp3;
|
||||
Vec_Int_t vNewNodes;
|
||||
Vec_Int_t vGateTfi;
|
||||
Vec_Int_t vGateTfo;
|
||||
Vec_Int_t vGateCut;
|
||||
Vec_Int_t vGateTemp;
|
||||
Vec_Int_t vGateMffc;
|
||||
Vec_Int_t vCands;
|
||||
word Copy[4];
|
||||
int nSuppVars;
|
||||
|
|
@ -281,9 +284,12 @@ void Sfm_DecStop( Sfm_Dec_t * p )
|
|||
Vec_WrdErase( &p->vSets[0] );
|
||||
Vec_WrdErase( &p->vSets[1] );
|
||||
// temporary
|
||||
Vec_IntErase( &p->vTemp );
|
||||
Vec_IntErase( &p->vTemp2 );
|
||||
Vec_IntErase( &p->vTemp3 );
|
||||
Vec_IntErase( &p->vNewNodes );
|
||||
Vec_IntErase( &p->vGateTfi );
|
||||
Vec_IntErase( &p->vGateTfo );
|
||||
Vec_IntErase( &p->vGateCut );
|
||||
Vec_IntErase( &p->vGateTemp );
|
||||
Vec_IntErase( &p->vGateMffc );
|
||||
Vec_IntErase( &p->vCands );
|
||||
ABC_FREE( p );
|
||||
pNtk->pData = NULL;
|
||||
|
|
@ -474,7 +480,7 @@ void Sfm_ObjSetdownSimInfo( Abc_Obj_t * pObj )
|
|||
int Sfm_DecPrepareSolver( Sfm_Dec_t * p )
|
||||
{
|
||||
Vec_Int_t * vRoots = &p->vObjRoots;
|
||||
Vec_Int_t * vFaninVars = &p->vTemp2;
|
||||
Vec_Int_t * vFaninVars = &p->vGateTemp;
|
||||
Vec_Int_t * vLevel, * vClause;
|
||||
int i, k, Gate, iObj, RetValue;
|
||||
int nTfiSize = p->iTarget + 1; // including node
|
||||
|
|
@ -1159,8 +1165,8 @@ int Sfm_DecPeformDec2( Sfm_Dec_t * p, Abc_Obj_t * pObj )
|
|||
|
||||
|
||||
// compute area savings
|
||||
Sfm_DecPrepareVec( &p->vObjMap, pSupp[i], nSupp[i], &p->vTemp );
|
||||
AreaThis = Sfm_DecMffcAreaReal(pObj, &p->vTemp, NULL);
|
||||
Sfm_DecPrepareVec( &p->vObjMap, pSupp[i], nSupp[i], &p->vGateCut );
|
||||
AreaThis = Sfm_DecMffcAreaReal(pObj, &p->vGateCut, NULL);
|
||||
assert( p->AreaMffc <= AreaThis );
|
||||
if ( p->pPars->fZeroCost ? (AreaNew > AreaThis) : (AreaNew >= AreaThis) )
|
||||
continue;
|
||||
|
|
@ -1203,7 +1209,7 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
|
|||
int nSupp[SFM_DEC_MAX], pAssump[SFM_WIN_MAX];
|
||||
int fVeryVerbose = p->pPars->fPrintDecs || p->pPars->fVeryVerbose;
|
||||
int nDecs = Abc_MaxInt(p->pPars->nDecMax, 1);
|
||||
int i, k, DelayOrig = 0, DelayMin, GainMax, nMatches, iBest = -1, RetValue, Prev = 0;
|
||||
int i, k, DelayOrig = 0, DelayMin, GainMax, AreaMffc, nMatches, iBest = -1, RetValue, Prev = 0;
|
||||
Mio_Gate_t * pGate1Best = NULL, * pGate2Best = NULL;
|
||||
char * pFans1Best = NULL, * pFans2Best = NULL;
|
||||
assert( p->pPars->fArea == 0 );
|
||||
|
|
@ -1262,11 +1268,8 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
|
|||
}
|
||||
|
||||
// get MFFC
|
||||
if ( p->pMit )
|
||||
{
|
||||
Sfm_DecPrepareVec( &p->vObjMap, pSupp[i], nSupp[i], &p->vTemp ); // returns cut in p->vTemp
|
||||
Sfm_DecMffcAreaReal(pObj, &p->vTemp, &p->vTemp3 ); // returns MFFC in p->vTemp3
|
||||
}
|
||||
Sfm_DecPrepareVec( &p->vObjMap, pSupp[i], nSupp[i], &p->vGateCut ); // returns cut in p->vGateCut
|
||||
AreaMffc = Sfm_DecMffcAreaReal(pObj, &p->vGateCut, &p->vGateMffc ); // returns MFFC in p->vGateMffc
|
||||
|
||||
// try the delay
|
||||
p->nSuppVars = nSupp[i];
|
||||
|
|
@ -1277,6 +1280,7 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
|
|||
abctime clk = Abc_Clock();
|
||||
Mio_Gate_t * pGate1 = (Mio_Gate_t *)Vec_PtrEntry( &p->vMatchGates, 2*k+0 );
|
||||
Mio_Gate_t * pGate2 = (Mio_Gate_t *)Vec_PtrEntry( &p->vMatchGates, 2*k+1 );
|
||||
int AreaNew = Scl_Flt2Int( Mio_GateReadArea(pGate1) + (pGate2 ? Mio_GateReadArea(pGate2) : 0.0) );
|
||||
char * pFans1 = (char *)Vec_PtrEntry( &p->vMatchFans, 2*k+0 );
|
||||
char * pFans2 = (char *)Vec_PtrEntry( &p->vMatchFans, 2*k+1 );
|
||||
Vec_Int_t vFanins = { nSupp[i], nSupp[i], pSupp[i] };
|
||||
|
|
@ -1285,7 +1289,9 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
|
|||
// continue;
|
||||
if ( p->pMit )
|
||||
{
|
||||
int Gain = Sfm_MitEvalRemapping( p->pMit, &p->vTemp3, pObj, &vFanins, &p->vObjMap, pGate1, pFans1, pGate2, pFans2 );
|
||||
int Gain = Sfm_MitEvalRemapping( p->pMit, &p->vGateMffc, pObj, &vFanins, &p->vObjMap, pGate1, pFans1, pGate2, pFans2 );
|
||||
if ( p->pPars->DelAreaRatio && AreaNew > AreaMffc && (Gain / (AreaNew - AreaMffc)) < p->pPars->DelAreaRatio )
|
||||
continue;
|
||||
if ( GainMax < Gain )
|
||||
{
|
||||
GainMax = Gain;
|
||||
|
|
@ -1299,6 +1305,8 @@ int Sfm_DecPeformDec3( Sfm_Dec_t * p, Abc_Obj_t * pObj )
|
|||
else
|
||||
{
|
||||
int Delay = Sfm_TimEvalRemapping( p->pTim, &vFanins, &p->vObjMap, pGate1, pFans1, pGate2, pFans2 );
|
||||
if ( p->pPars->DelAreaRatio && AreaNew > AreaMffc && (Delay / (AreaNew - AreaMffc)) < p->pPars->DelAreaRatio )
|
||||
continue;
|
||||
if ( DelayMin > Delay )
|
||||
{
|
||||
DelayMin = Delay;
|
||||
|
|
@ -1690,13 +1698,13 @@ printf( "\n" );
|
|||
*/
|
||||
return nDivs;
|
||||
}
|
||||
Abc_Obj_t * Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t * vGates, Vec_Wec_t * vFanins, Vec_Int_t * vMap, Vec_Ptr_t * vGateHandles, int GateBuf, int GateInv, Vec_Wrd_t * vFuncs, Vec_Int_t * vTimeNodes, Sfm_Mit_t * pMit )
|
||||
Abc_Obj_t * Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t * vGates, Vec_Wec_t * vFanins, Vec_Int_t * vMap, Vec_Ptr_t * vGateHandles, int GateBuf, int GateInv, Vec_Wrd_t * vFuncs, Vec_Int_t * vNewNodes, Sfm_Mit_t * pMit )
|
||||
{
|
||||
Abc_Obj_t * pObjNew = NULL;
|
||||
Vec_Int_t * vLevel;
|
||||
int i, k, iObj, Gate;
|
||||
if ( vTimeNodes )
|
||||
Vec_IntClear( vTimeNodes );
|
||||
if ( vNewNodes )
|
||||
Vec_IntClear( vNewNodes );
|
||||
// assuming that new gates are appended at the end
|
||||
assert( Limit < Vec_IntSize(vGates) );
|
||||
assert( Limit == Vec_IntSize(vMap) );
|
||||
|
|
@ -1715,11 +1723,11 @@ Abc_Obj_t * Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_
|
|||
// update level
|
||||
pObjNew->Level = 0;
|
||||
Abc_NtkUpdateIncLevel_rec( pObjNew );
|
||||
if ( vTimeNodes )
|
||||
Vec_IntPush( vTimeNodes, Abc_ObjId(pObjNew) );
|
||||
if ( vNewNodes )
|
||||
Vec_IntPush( vNewNodes, Abc_ObjId(pObjNew) );
|
||||
return pObjNew;
|
||||
}
|
||||
else if ( vTimeNodes == NULL && Gate == GateInv )
|
||||
else if ( vNewNodes == NULL && Gate == GateInv )
|
||||
{
|
||||
// check if fanouts can be updated
|
||||
Abc_Obj_t * pFanout;
|
||||
|
|
@ -1764,8 +1772,8 @@ Abc_Obj_t * Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_
|
|||
pObjNew->pData = Vec_PtrEntry( vGateHandles, Gate );
|
||||
assert( Abc_ObjFaninNum(pObjNew) == Mio_GateReadPinNum((Mio_Gate_t *)pObjNew->pData) );
|
||||
Vec_IntPush( vMap, Abc_ObjId(pObjNew) );
|
||||
if ( vTimeNodes )
|
||||
Vec_IntPush( vTimeNodes, Abc_ObjId(pObjNew) );
|
||||
if ( vNewNodes )
|
||||
Vec_IntPush( vNewNodes, Abc_ObjId(pObjNew) );
|
||||
}
|
||||
// transfer load
|
||||
if ( pMit )
|
||||
|
|
@ -1865,7 +1873,7 @@ Abc_Obj_t * Abc_NtkAreaOptOne( Sfm_Dec_t * p, int i )
|
|||
pPars->fVeryVerbose = (int)(i == pPars->iNodeOne);
|
||||
p->nNodesTried++;
|
||||
clk = Abc_Clock();
|
||||
p->nDivs = Sfm_DecExtract( pNtk, pPars, pObj, &p->vObjRoots, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vTemp, &p->vTemp2, &p->vObjMffc, &p->vObjInMffc, NULL, NULL );
|
||||
p->nDivs = Sfm_DecExtract( pNtk, pPars, pObj, &p->vObjRoots, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vGateTfi, &p->vGateTfo, &p->vObjMffc, &p->vObjInMffc, NULL, NULL );
|
||||
p->timeWin += Abc_Clock() - clk;
|
||||
if ( pPars->nWinSizeMax && pPars->nWinSizeMax < Vec_IntSize(&p->vObjGates) )
|
||||
return NULL;
|
||||
|
|
@ -1997,7 +2005,7 @@ void Abc_NtkDelayOpt( Sfm_Dec_t * p )
|
|||
assert( pObj->fMarkA == 0 );
|
||||
p->nNodesTried++;
|
||||
clk = Abc_Clock();
|
||||
p->nDivs = Sfm_DecExtract( pNtk, pPars, pObj, &p->vObjRoots, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vTemp, &p->vTemp2, &p->vObjMffc, &p->vObjInMffc, p->pTim, p->pMit );
|
||||
p->nDivs = Sfm_DecExtract( pNtk, pPars, pObj, &p->vObjRoots, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vGateTfi, &p->vGateTfo, &p->vObjMffc, &p->vObjInMffc, p->pTim, p->pMit );
|
||||
p->timeWin += Abc_Clock() - clk;
|
||||
if ( p->nDivs < 2 || (pPars->nWinSizeMax && pPars->nWinSizeMax < Vec_IntSize(&p->vObjGates)) )
|
||||
{
|
||||
|
|
@ -2059,15 +2067,15 @@ p->timeSat += Abc_Clock() - clk;
|
|||
p->nNodesChanged++;
|
||||
Abc_NtkCountStats( p, Limit );
|
||||
// reduce load due to removed MFFC
|
||||
if ( p->pMit ) Sfm_MitUpdateLoad( p->pMit, &p->vTemp3, 0 ); // assuming &p->vTemp3 contains MFFC
|
||||
Sfm_DecInsert( pNtk, pObj, Limit, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vGateHands, p->GateBuffer, p->GateInvert, &p->vGateFuncs, &p->vTemp, p->pMit );
|
||||
if ( p->pMit ) Sfm_MitUpdateLoad( p->pMit, &p->vGateMffc, 0 ); // assuming &p->vGateMffc contains MFFC
|
||||
Sfm_DecInsert( pNtk, pObj, Limit, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vGateHands, p->GateBuffer, p->GateInvert, &p->vGateFuncs, &p->vNewNodes, p->pMit );
|
||||
// increase load due to added new nodes
|
||||
if ( p->pMit ) Sfm_MitUpdateLoad( p->pMit, &p->vTemp, 1 ); // assuming &p->vTemp contains new nodes
|
||||
if ( p->pMit ) Sfm_MitUpdateLoad( p->pMit, &p->vNewNodes, 1 ); // assuming &p->vNewNodes contains new nodes
|
||||
clk = Abc_Clock();
|
||||
if ( p->pMit )
|
||||
Sfm_MitUpdateTiming( p->pMit, &p->vTemp );
|
||||
Sfm_MitUpdateTiming( p->pMit, &p->vNewNodes );
|
||||
else
|
||||
Sfm_TimUpdateTiming( p->pTim, &p->vTemp );
|
||||
Sfm_TimUpdateTiming( p->pTim, &p->vNewNodes );
|
||||
p->timeTime += Abc_Clock() - clk;
|
||||
pObjNew = Abc_NtkObj( pNtk, Abc_NtkObjNumMax(pNtk)-1 );
|
||||
assert( p->pMit || p->DelayMin == 0 || p->DelayMin == Sfm_ManReadObjDelay(p, Abc_ObjId(pObjNew)) );
|
||||
|
|
|
|||
|
|
@ -288,6 +288,7 @@ void Sfm_LibTruth8Two( Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
/*
|
||||
void Sfm_LibCellProfile( Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop, int nFanins, int * Perm, int * pProf )
|
||||
{
|
||||
int i, DelayAdd = pCellTop ? pCellTop->iDelays[InTop] : 0;
|
||||
|
|
@ -299,6 +300,18 @@ void Sfm_LibCellProfile( Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InT
|
|||
else // if ( Perm[i] >= (int)pCellBot->nFanins + InTop )
|
||||
pProf[i] = pCellTop->iDelays[Perm[i] - (int)pCellBot->nFanins + 1];
|
||||
}
|
||||
*/
|
||||
void Sfm_LibCellProfile( Mio_Cell2_t * pCellBot, Mio_Cell2_t * pCellTop, int InTop, int nFanins, int * Perm, int * pProf )
|
||||
{
|
||||
int i, DelayAdd = pCellTop ? 1 : 0;
|
||||
for ( i = 0; i < nFanins; i++ )
|
||||
if ( Perm[i] < (int)pCellBot->nFanins )
|
||||
pProf[i] = 1 + DelayAdd;
|
||||
else if ( Perm[i] < (int)pCellBot->nFanins + InTop )
|
||||
pProf[i] = 1;
|
||||
else // if ( Perm[i] >= (int)pCellBot->nFanins + InTop )
|
||||
pProf[i] = 1;
|
||||
}
|
||||
static inline int Sfm_LibNewIsContained( Sfm_Fun_t * pObj, int * pProf, int Area, int * pProfNew, int nFanins )
|
||||
{
|
||||
int k;
|
||||
|
|
|
|||
Loading…
Reference in New Issue