Commit 229ee5df by Alan Mishchenko

Enabling reverse topo order in area minimization.

parent 9521d134
...@@ -5194,7 +5194,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -5194,7 +5194,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults // set defaults
Sfm_ParSetDefault3( pPars ); Sfm_ParSetDefault3( pPars );
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "IOVFKLHRMCNPWDdamzospdlvwh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "IOVFKLHRMCNPWDarmzospdlvwh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -5358,6 +5358,9 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -5358,6 +5358,9 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'a': case 'a':
pPars->fArea ^= 1; pPars->fArea ^= 1;
break; break;
case 'r':
pPars->fAreaRev ^= 1;
break;
case 'm': case 'm':
pPars->fUseAndOr ^= 1; pPars->fUseAndOr ^= 1;
break; break;
...@@ -5406,7 +5409,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -5406,7 +5409,7 @@ int Abc_CommandMfs3( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
Abc_Print( -2, "usage: mfs3 [-IOVFKLHRMCNPWD <num>] [-amzospdlvwh]\n" ); Abc_Print( -2, "usage: mfs3 [-IOVFKLHRMCNPWD <num>] [-armzospdlvwh]\n" );
Abc_Print( -2, "\t performs don't-care-based optimization of mapped networks\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-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 ); Abc_Print( -2, "\t-O <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevMax );
...@@ -5423,6 +5426,7 @@ usage: ...@@ -5423,6 +5426,7 @@ usage:
Abc_Print( -2, "\t-W <num> : size of timing window in percents (0 <= num <= 100) [default = %d]\n", pPars->nTimeWin ); 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-D <num> : size of critical-timing delay-delta (in picoseconds) [default = %d]\n", pPars->DeltaCrit );
Abc_Print( -2, "\t-a : toggle area minimization [default = %s]\n", pPars->fArea? "yes": "no" ); 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" ); Abc_Print( -2, "\t-m : toggle detecting multi-input AND/OR gates [default = %s]\n", pPars->fUseAndOr? "yes": "no" );
Abc_Print( -2, "\t-z : toggle zero-cost replacements [default = %s]\n", pPars->fZeroCost? "yes": "no" ); Abc_Print( -2, "\t-z : toggle zero-cost replacements [default = %s]\n", pPars->fZeroCost? "yes": "no" );
Abc_Print( -2, "\t-o : toggle using old implementation for comparison [default = %s]\n", pPars->fRrOnly? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using old implementation for comparison [default = %s]\n", pPars->fRrOnly? "yes": "no" );
...@@ -60,6 +60,7 @@ struct Sfm_Par_t_ ...@@ -60,6 +60,7 @@ struct Sfm_Par_t_
int DeltaCrit; // delay delta in picoseconds int DeltaCrit; // delay delta in picoseconds
int fRrOnly; // perform redundance removal int fRrOnly; // perform redundance removal
int fArea; // performs optimization for area int fArea; // performs optimization for area
int fAreaRev; // performs optimization for area in reverse order
int fMoreEffort; // performs high-affort minimization int fMoreEffort; // performs high-affort minimization
int fUseAndOr; // enable internal detection of AND/OR gates int fUseAndOr; // enable internal detection of AND/OR gates
int fZeroCost; // enable zero-cost replacement int fZeroCost; // enable zero-cost replacement
......
...@@ -1699,7 +1699,7 @@ printf( "\n" ); ...@@ -1699,7 +1699,7 @@ printf( "\n" );
*/ */
return nDivs; return nDivs;
} }
void 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 ) 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 )
{ {
Abc_Obj_t * pObjNew = NULL; Abc_Obj_t * pObjNew = NULL;
Vec_Int_t * vLevel; Vec_Int_t * vLevel;
...@@ -1722,7 +1722,7 @@ void Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t * ...@@ -1722,7 +1722,7 @@ void Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t *
Abc_NtkUpdateIncLevel_rec( pObjNew ); Abc_NtkUpdateIncLevel_rec( pObjNew );
if ( vTimeNodes ) if ( vTimeNodes )
Vec_IntPush( vTimeNodes, Abc_ObjId(pObjNew) ); Vec_IntPush( vTimeNodes, Abc_ObjId(pObjNew) );
return; return pObjNew;
} }
else if ( vTimeNodes == NULL && Gate == GateInv ) else if ( vTimeNodes == NULL && Gate == GateInv )
{ {
...@@ -1755,7 +1755,7 @@ void Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t * ...@@ -1755,7 +1755,7 @@ void Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t *
// update level // update level
pObjNew->Level = 0; pObjNew->Level = 0;
Abc_NtkUpdateIncLevel_rec( pObjNew ); Abc_NtkUpdateIncLevel_rec( pObjNew );
return; return pObjNew;
} }
} }
} }
...@@ -1776,6 +1776,7 @@ void Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t * ...@@ -1776,6 +1776,7 @@ void Sfm_DecInsert( Abc_Ntk_t * pNtk, Abc_Obj_t * pPivot, int Limit, Vec_Int_t *
// update level // update level
Abc_NtkForEachObjVecStart( vMap, pNtk, pObjNew, i, Limit ) Abc_NtkForEachObjVecStart( vMap, pNtk, pObjNew, i, Limit )
Abc_NtkUpdateIncLevel_rec( pObjNew ); Abc_NtkUpdateIncLevel_rec( pObjNew );
return pObjNew;
} }
void Sfm_DecPrintStats( Sfm_Dec_t * p ) void Sfm_DecPrintStats( Sfm_Dec_t * p )
{ {
...@@ -1846,57 +1847,108 @@ void Abc_NtkCountStats( Sfm_Dec_t * p, int Limit ) ...@@ -1846,57 +1847,108 @@ void Abc_NtkCountStats( Sfm_Dec_t * p, int Limit )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_NtkAreaOpt( Sfm_Dec_t * p ) Abc_Obj_t * Abc_NtkAreaOptOne( Sfm_Dec_t * p, int i )
{ {
abctime clk;
Abc_Ntk_t * pNtk = p->pNtk; Abc_Ntk_t * pNtk = p->pNtk;
Sfm_Par_t * pPars = p->pPars; Sfm_Par_t * pPars = p->pPars;
Abc_Obj_t * pObj; Abc_Obj_t * pObj = Abc_NtkObj( p->pNtk, i );
abctime clk; int Limit, RetValue, nStop = Abc_NtkObjNumMax(pNtk);
int i = 0, Limit, RetValue, nStop = Abc_NtkObjNumMax(pNtk); if ( pPars->nMffcMin > 1 && Abc_NodeMffcLabel(pObj) < pPars->nMffcMin )
Abc_NtkForEachNode( pNtk, pObj, i ) return NULL;
{ if ( pPars->iNodeOne && i != pPars->iNodeOne )
if ( i >= nStop || (pPars->nNodesMax && i > pPars->nNodesMax) ) return NULL;
break; if ( pPars->iNodeOne )
if ( pPars->nMffcMin > 1 && Abc_NodeMffcLabel(pObj) < pPars->nMffcMin ) pPars->fVeryVerbose = (int)(i == pPars->iNodeOne);
continue; p->nNodesTried++;
if ( pPars->iNodeOne && i != pPars->iNodeOne )
continue;
if ( pPars->iNodeOne )
pPars->fVeryVerbose = (int)(i == pPars->iNodeOne);
p->nNodesTried++;
clk = Abc_Clock(); 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 ); p->nDivs = Sfm_DecExtract( pNtk, pPars, pObj, &p->vObjRoots, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vTemp, &p->vTemp2, &p->vObjMffc, &p->vObjInMffc, NULL );
p->timeWin += Abc_Clock() - clk; p->timeWin += Abc_Clock() - clk;
if ( pPars->nWinSizeMax && pPars->nWinSizeMax < Vec_IntSize(&p->vObjGates) ) if ( pPars->nWinSizeMax && pPars->nWinSizeMax < Vec_IntSize(&p->vObjGates) )
continue; return NULL;
p->nMffc = Vec_IntSize(&p->vObjMffc); p->nMffc = Vec_IntSize(&p->vObjMffc);
p->AreaMffc = Sfm_DecMffcArea(pNtk, &p->vObjMffc); p->AreaMffc = Sfm_DecMffcArea(pNtk, &p->vObjMffc);
p->nMaxDivs = Abc_MaxInt( p->nMaxDivs, p->nDivs ); p->nMaxDivs = Abc_MaxInt( p->nMaxDivs, p->nDivs );
p->nAllDivs += p->nDivs; p->nAllDivs += p->nDivs;
p->iTarget = pObj->iTemp; p->iTarget = pObj->iTemp;
Limit = Vec_IntSize( &p->vObjGates ); Limit = Vec_IntSize( &p->vObjGates );
p->nMaxWin = Abc_MaxInt( p->nMaxWin, Limit ); p->nMaxWin = Abc_MaxInt( p->nMaxWin, Limit );
p->nAllWin += Limit; p->nAllWin += Limit;
clk = Abc_Clock(); clk = Abc_Clock();
RetValue = Sfm_DecPrepareSolver( p ); RetValue = Sfm_DecPrepareSolver( p );
p->timeCnf += Abc_Clock() - clk; p->timeCnf += Abc_Clock() - clk;
if ( !RetValue ) if ( !RetValue )
continue; return NULL;
clk = Abc_Clock(); clk = Abc_Clock();
if ( pPars->fRrOnly ) if ( pPars->fRrOnly )
RetValue = Sfm_DecPeformDec( p ); RetValue = Sfm_DecPeformDec( p );
else else
RetValue = Sfm_DecPeformDec2( p, pObj ); RetValue = Sfm_DecPeformDec2( p, pObj );
if ( p->pPars->fVeryVerbose ) if ( p->pPars->fVeryVerbose )
printf( "\n\n" ); printf( "\n\n" );
p->timeSat += Abc_Clock() - clk; p->timeSat += Abc_Clock() - clk;
if ( RetValue < 0 ) if ( RetValue < 0 )
return NULL;
p->nNodesChanged++;
Abc_NtkCountStats( p, Limit );
return Sfm_DecInsert( pNtk, pObj, Limit, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vGateHands, p->GateBuffer, p->GateInvert, &p->vGateFuncs, NULL );
}
void Abc_NtkAreaOpt( Sfm_Dec_t * p )
{
Abc_Obj_t * pObj;
int i, nStop = Abc_NtkObjNumMax(p->pNtk);
Abc_NtkForEachNode( p->pNtk, pObj, i )
{
if ( i >= nStop || (p->pPars->nNodesMax && i > p->pPars->nNodesMax) )
break;
Abc_NtkAreaOptOne( p, i );
}
}
void Abc_NtkAreaOpt2( Sfm_Dec_t * p )
{
Abc_Obj_t * pObj, * pObjNew, * pFanin;
int i, k, nStop = Abc_NtkObjNumMax(p->pNtk);
Vec_Ptr_t * vFront = Vec_PtrAlloc( 1000 );
Abc_NtkForEachObj( p->pNtk, pObj, i )
assert( pObj->fMarkB == 0 );
// start the queue of nodes to be tried
Abc_NtkForEachCo( p->pNtk, pObj, i )
if ( Abc_ObjIsNode(Abc_ObjFanin0(pObj)) && !Abc_ObjFanin0(pObj)->fMarkB )
{
Abc_ObjFanin0(pObj)->fMarkB = 1;
Vec_PtrPush( vFront, Abc_ObjFanin0(pObj) );
}
// process nodes in this order
Vec_PtrForEachEntry( Abc_Obj_t *, vFront, pObj, i )
{
if ( Abc_ObjIsNone(pObj) )
continue; continue;
p->nNodesChanged++; pObjNew = Abc_NtkAreaOptOne( p, Abc_ObjId(pObj) );
Abc_NtkCountStats( p, Limit ); if ( pObjNew != NULL )
Sfm_DecInsert( pNtk, pObj, Limit, &p->vObjGates, &p->vObjFanins, &p->vObjMap, &p->vGateHands, p->GateBuffer, p->GateInvert, &p->vGateFuncs, NULL ); {
if ( !Abc_ObjIsNode(pObjNew) || Abc_ObjFaninNum(pObjNew) == 0 || pObjNew->fMarkB )
continue;
if ( (int)Abc_ObjId(pObjNew) < nStop )
{
pObjNew->fMarkB = 1;
Vec_PtrPush( vFront, pObjNew );
continue;
}
}
else
pObjNew = pObj;
Abc_ObjForEachFanin( pObjNew, pFanin, k )
if ( Abc_ObjIsNode(pFanin) && Abc_ObjFaninNum(pObjNew) > 0 && !pFanin->fMarkB )
{
pFanin->fMarkB = 1;
Vec_PtrPush( vFront, pFanin );
}
} }
Abc_NtkForEachObj( p->pNtk, pObj, i )
pObj->fMarkB = 0;
Vec_PtrFree( vFront );
} }
void Abc_NtkDelayOpt( Sfm_Dec_t * p ) void Abc_NtkDelayOpt( Sfm_Dec_t * p )
{ {
Abc_Ntk_t * pNtk = p->pNtk; Abc_Ntk_t * pNtk = p->pNtk;
...@@ -2018,7 +2070,12 @@ void Abc_NtkPerformMfs3( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars ) ...@@ -2018,7 +2070,12 @@ void Abc_NtkPerformMfs3( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
if ( pPars->fVerbose ) p->nTotalEdgesBeg = Abc_NtkGetTotalFanins(pNtk); if ( pPars->fVerbose ) p->nTotalEdgesBeg = Abc_NtkGetTotalFanins(pNtk);
// perform optimization // perform optimization
if ( pPars->fArea ) if ( pPars->fArea )
Abc_NtkAreaOpt( p ); {
if ( pPars->fAreaRev )
Abc_NtkAreaOpt2( p );
else
Abc_NtkAreaOpt( p );
}
else else
Abc_NtkDelayOpt( p ); Abc_NtkDelayOpt( p );
// record statistics // record statistics
......
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