mirror of https://github.com/YosysHQ/abc.git
New flavor of DSD-friendly 'eliminate'.
This commit is contained in:
parent
1398de7c46
commit
a1fa224d61
|
|
@ -562,7 +562,9 @@ Gia_Man_t * Gia_ManDup( Gia_Man_t * p )
|
||||||
Gia_ManConst0(p)->Value = 0;
|
Gia_ManConst0(p)->Value = 0;
|
||||||
Gia_ManForEachObj1( p, pObj, i )
|
Gia_ManForEachObj1( p, pObj, i )
|
||||||
{
|
{
|
||||||
if ( Gia_ObjIsAnd(pObj) )
|
if ( Gia_ObjIsBarBuf(pObj) )
|
||||||
|
pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||||
|
else if ( Gia_ObjIsAnd(pObj) )
|
||||||
{
|
{
|
||||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||||
if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
|
if ( Gia_ObjSibl(p, Gia_ObjId(p, pObj)) )
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,8 @@ Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit )
|
||||||
pObj->Value = Gia_ManAppendCi( pNew );
|
pObj->Value = Gia_ManAppendCi( pNew );
|
||||||
else if ( Gia_ObjIsCo(pObj) )
|
else if ( Gia_ObjIsCo(pObj) )
|
||||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||||
|
else if ( Gia_ObjIsBarBuf(pObj) )
|
||||||
|
pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||||
else if ( !Gia_ObjIsMuxType(pObj) || Gia_ObjSibl(p, Gia_ObjFaninId0(pObj, i)) || Gia_ObjSibl(p, Gia_ObjFaninId1(pObj, i)) )
|
else if ( !Gia_ObjIsMuxType(pObj) || Gia_ObjSibl(p, Gia_ObjFaninId0(pObj, i)) || Gia_ObjSibl(p, Gia_ObjFaninId1(pObj, i)) )
|
||||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||||
else if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
|
else if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
|
||||||
|
|
@ -172,6 +174,8 @@ Gia_Man_t * Gia_ManDupNoMuxes( Gia_Man_t * p )
|
||||||
pObj->Value = Gia_ManAppendCi( pNew );
|
pObj->Value = Gia_ManAppendCi( pNew );
|
||||||
else if ( Gia_ObjIsCo(pObj) )
|
else if ( Gia_ObjIsCo(pObj) )
|
||||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||||
|
else if ( Gia_ObjIsBarBuf(pObj) )
|
||||||
|
pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||||
else if ( Gia_ObjIsMuxId(p, i) )
|
else if ( Gia_ObjIsMuxId(p, i) )
|
||||||
pObj->Value = Gia_ManHashMux( pNew, Gia_ObjFanin2Copy(p, pObj), Gia_ObjFanin1Copy(pObj), Gia_ObjFanin0Copy(pObj) );
|
pObj->Value = Gia_ManHashMux( pNew, Gia_ObjFanin2Copy(p, pObj), Gia_ObjFanin1Copy(pObj), Gia_ObjFanin0Copy(pObj) );
|
||||||
else if ( Gia_ObjIsXor(pObj) )
|
else if ( Gia_ObjIsXor(pObj) )
|
||||||
|
|
|
||||||
|
|
@ -357,7 +357,7 @@ static inline int Abc_ObjIsLatch( Abc_Obj_t * pObj ) { return pO
|
||||||
static inline int Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_WHITEBOX || pObj->Type == ABC_OBJ_BLACKBOX; }
|
static inline int Abc_ObjIsBox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_LATCH || pObj->Type == ABC_OBJ_WHITEBOX || pObj->Type == ABC_OBJ_BLACKBOX; }
|
||||||
static inline int Abc_ObjIsWhitebox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_WHITEBOX;}
|
static inline int Abc_ObjIsWhitebox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_WHITEBOX;}
|
||||||
static inline int Abc_ObjIsBlackbox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BLACKBOX;}
|
static inline int Abc_ObjIsBlackbox( Abc_Obj_t * pObj ) { return pObj->Type == ABC_OBJ_BLACKBOX;}
|
||||||
static inline int Abc_ObjIsBarBuf( Abc_Obj_t * pObj ) { assert( Abc_NtkIsLogic(pObj->pNtk) ); return Vec_IntSize(&pObj->vFanins) == 1 && pObj->pData == NULL; }
|
static inline int Abc_ObjIsBarBuf( Abc_Obj_t * pObj ) { return Abc_NtkIsLogic(pObj->pNtk) && Vec_IntSize(&pObj->vFanins) == 1 && pObj->pData == NULL; }
|
||||||
static inline void Abc_ObjBlackboxToWhitebox( Abc_Obj_t * pObj ) { assert( Abc_ObjIsBlackbox(pObj) ); pObj->Type = ABC_OBJ_WHITEBOX; pObj->pNtk->nObjCounts[ABC_OBJ_BLACKBOX]--; pObj->pNtk->nObjCounts[ABC_OBJ_WHITEBOX]++; }
|
static inline void Abc_ObjBlackboxToWhitebox( Abc_Obj_t * pObj ) { assert( Abc_ObjIsBlackbox(pObj) ); pObj->Type = ABC_OBJ_WHITEBOX; pObj->pNtk->nObjCounts[ABC_OBJ_BLACKBOX]--; pObj->pNtk->nObjCounts[ABC_OBJ_WHITEBOX]++; }
|
||||||
|
|
||||||
// working with fanin/fanout edges
|
// working with fanin/fanout edges
|
||||||
|
|
|
||||||
|
|
@ -675,6 +675,147 @@ int Abc_NtkEliminate1( Abc_Ntk_t * pNtk, int ElimValue, int nMaxSize, int nIterM
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Sort nodes in the reverse topo order.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_ObjCompareByNumber( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
|
||||||
|
{
|
||||||
|
return Abc_ObjRegular(*pp1)->iTemp - Abc_ObjRegular(*pp2)->iTemp;
|
||||||
|
}
|
||||||
|
void Abc_ObjSortInReverseOrder( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
|
||||||
|
{
|
||||||
|
Vec_Ptr_t * vOrder;
|
||||||
|
Abc_Obj_t * pNode;
|
||||||
|
int i;
|
||||||
|
vOrder = Abc_NtkDfsReverse( pNtk );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pNode, i )
|
||||||
|
pNode->iTemp = i;
|
||||||
|
Vec_PtrSort( vNodes, (int (*)())Abc_ObjCompareByNumber );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pNode, i )
|
||||||
|
pNode->iTemp = 0;
|
||||||
|
Vec_PtrFree( vOrder );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**Function*************************************************************
|
||||||
|
|
||||||
|
Synopsis [Performs traditional eliminate -1.]
|
||||||
|
|
||||||
|
Description []
|
||||||
|
|
||||||
|
SideEffects []
|
||||||
|
|
||||||
|
SeeAlso []
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
int Abc_NtkEliminateSpecial( Abc_Ntk_t * pNtk, int nMaxSize, int fVerbose )
|
||||||
|
{
|
||||||
|
extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose );
|
||||||
|
Vec_Ptr_t * vFanouts, * vFanins, * vNodes;
|
||||||
|
Abc_Obj_t * pNode, * pFanout;
|
||||||
|
int * pPermFanin, * pPermFanout;
|
||||||
|
int RetValue, i, k;
|
||||||
|
assert( nMaxSize > 0 );
|
||||||
|
assert( Abc_NtkIsLogic(pNtk) );
|
||||||
|
|
||||||
|
|
||||||
|
// convert network to BDD representation
|
||||||
|
if ( !Abc_NtkToBdd(pNtk) )
|
||||||
|
{
|
||||||
|
fprintf( stdout, "Converting to BDD has failed.\n" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare nodes for sweeping
|
||||||
|
Abc_NtkRemoveDupFanins( pNtk );
|
||||||
|
Abc_NtkMinimumBase( pNtk );
|
||||||
|
Abc_NtkCleanup( pNtk, 0 );
|
||||||
|
|
||||||
|
// convert network to SOPs
|
||||||
|
if ( !Abc_NtkToSop(pNtk, 0) )
|
||||||
|
{
|
||||||
|
fprintf( stdout, "Converting to SOP has failed.\n" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect info about the nodes to be eliminated
|
||||||
|
vNodes = Vec_PtrAlloc( 1000 );
|
||||||
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
|
{
|
||||||
|
if ( Abc_ObjFanoutNum(pNode) != 1 )
|
||||||
|
continue;
|
||||||
|
pFanout = Abc_ObjFanout0(pNode);
|
||||||
|
if ( !Abc_ObjIsNode(pFanout) )
|
||||||
|
continue;
|
||||||
|
if ( Abc_SopGetCubeNum((char *)pNode->pData) != 1 )
|
||||||
|
continue;
|
||||||
|
if ( Abc_SopGetCubeNum((char *)pFanout->pData) != 1 )
|
||||||
|
continue;
|
||||||
|
// find the fanout's fanin
|
||||||
|
RetValue = Abc_NodeFindFanin( pFanout, pNode );
|
||||||
|
assert( RetValue >= 0 && RetValue < Abc_ObjFaninNum(pFanout) );
|
||||||
|
// both pNode and pFanout are AND/OR type nodes
|
||||||
|
if ( Abc_SopIsComplement((char *)pNode->pData) == Abc_SopGetIthCareLit((char *)pFanout->pData, RetValue) )
|
||||||
|
continue;
|
||||||
|
Vec_PtrPush( vNodes, pNode );
|
||||||
|
}
|
||||||
|
if ( Vec_PtrSize(vNodes) == 0 )
|
||||||
|
{
|
||||||
|
Vec_PtrFree( vNodes );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Abc_ObjSortInReverseOrder( pNtk, vNodes );
|
||||||
|
|
||||||
|
// convert network to BDD representation
|
||||||
|
if ( !Abc_NtkToBdd(pNtk) )
|
||||||
|
{
|
||||||
|
fprintf( stdout, "Converting to BDD has failed.\n" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// go through the nodes and decide is they can be eliminated
|
||||||
|
pPermFanin = ABC_ALLOC( int, nMaxSize + 1000 );
|
||||||
|
pPermFanout = ABC_ALLOC( int, nMaxSize + 1000 );
|
||||||
|
vFanins = Vec_PtrAlloc( 1000 );
|
||||||
|
vFanouts = Vec_PtrAlloc( 1000 );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
|
||||||
|
{
|
||||||
|
assert( Abc_ObjIsNode(pNode) );
|
||||||
|
assert( Abc_NodeFindCoFanout(pNode) == NULL );
|
||||||
|
// perform elimination
|
||||||
|
Abc_NodeCollectFanouts( pNode, vFanouts );
|
||||||
|
Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, k )
|
||||||
|
{
|
||||||
|
if ( fVerbose )
|
||||||
|
printf( "Collapsing fanin %5d (supp =%2d) into fanout %5d (supp =%2d) ",
|
||||||
|
Abc_ObjId(pNode), Abc_ObjFaninNum(pNode), Abc_ObjId(pFanout), Abc_ObjFaninNum(pFanout) );
|
||||||
|
RetValue = Abc_NodeCollapse( pNode, pFanout, vFanins, pPermFanin, pPermFanout );
|
||||||
|
assert( RetValue );
|
||||||
|
if ( fVerbose )
|
||||||
|
{
|
||||||
|
Abc_Obj_t * pNodeNew = Abc_NtkObj( pNtk, Abc_NtkObjNumMax(pNtk) - 1 );
|
||||||
|
if ( pNodeNew )
|
||||||
|
printf( "resulting in node %5d (supp =%2d).\n", Abc_ObjId(pNodeNew), Abc_ObjFaninNum(pNodeNew) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Abc_NtkBddReorder( pNtk, 0 );
|
||||||
|
Vec_PtrFree( vFanins );
|
||||||
|
Vec_PtrFree( vFanouts );
|
||||||
|
Vec_PtrFree( vNodes );
|
||||||
|
ABC_FREE( pPermFanin );
|
||||||
|
ABC_FREE( pPermFanout );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
/// END OF FILE ///
|
/// END OF FILE ///
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -3909,10 +3909,12 @@ int Abc_CommandEliminate( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
int nIterMax;
|
int nIterMax;
|
||||||
int fGreedy;
|
int fGreedy;
|
||||||
int fReverse;
|
int fReverse;
|
||||||
|
int fSpecial;
|
||||||
int fVerbose;
|
int fVerbose;
|
||||||
int c;
|
int c;
|
||||||
extern int Abc_NtkEliminate( Abc_Ntk_t * pNtk, int nMaxSize, int fReverse, int fVerbose );
|
extern int Abc_NtkEliminate( Abc_Ntk_t * pNtk, int nMaxSize, int fReverse, int fVerbose );
|
||||||
extern int Abc_NtkEliminate1( Abc_Ntk_t * pNtk, int ElimValue, int nMaxSize, int nIterMax, int fReverse, int fVerbose );
|
extern int Abc_NtkEliminate1( Abc_Ntk_t * pNtk, int ElimValue, int nMaxSize, int nIterMax, int fReverse, int fVerbose );
|
||||||
|
extern int Abc_NtkEliminateSpecial( Abc_Ntk_t * pNtk, int nMaxSize, int fVerbose );
|
||||||
|
|
||||||
// set the defaults
|
// set the defaults
|
||||||
ElimValue = -1;
|
ElimValue = -1;
|
||||||
|
|
@ -3920,9 +3922,10 @@ int Abc_CommandEliminate( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
nIterMax = 1;
|
nIterMax = 1;
|
||||||
fGreedy = 0;
|
fGreedy = 0;
|
||||||
fReverse = 0;
|
fReverse = 0;
|
||||||
|
fSpecial = 0;
|
||||||
fVerbose = 0;
|
fVerbose = 0;
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
while ( (c = Extra_UtilGetopt(argc, argv, "VNIgrvh")) != EOF )
|
while ( (c = Extra_UtilGetopt(argc, argv, "VNIgrsvh")) != EOF )
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
|
@ -3965,6 +3968,9 @@ int Abc_CommandEliminate( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
case 'r':
|
case 'r':
|
||||||
fReverse ^= 1;
|
fReverse ^= 1;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
fSpecial ^= 1;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
fVerbose ^= 1;
|
fVerbose ^= 1;
|
||||||
break;
|
break;
|
||||||
|
|
@ -3994,14 +4000,16 @@ int Abc_CommandEliminate( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( fGreedy )
|
if ( fSpecial )
|
||||||
|
Abc_NtkEliminateSpecial( pNtk, 1000, fVerbose );
|
||||||
|
else if ( fGreedy )
|
||||||
Abc_NtkEliminate( pNtk, nMaxSize, fReverse, fVerbose );
|
Abc_NtkEliminate( pNtk, nMaxSize, fReverse, fVerbose );
|
||||||
else
|
else
|
||||||
Abc_NtkEliminate1( pNtk, ElimValue, nMaxSize, nIterMax, fReverse, fVerbose );
|
Abc_NtkEliminate1( pNtk, ElimValue, nMaxSize, nIterMax, fReverse, fVerbose );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
Abc_Print( -2, "usage: eliminate [-VNI <num>] [-grvh]\n");
|
Abc_Print( -2, "usage: eliminate [-VNI <num>] [-grsvh]\n");
|
||||||
Abc_Print( -2, "\t traditional \"eliminate -1\", which collapses the node into its fanout\n");
|
Abc_Print( -2, "\t traditional \"eliminate -1\", which collapses the node into its fanout\n");
|
||||||
Abc_Print( -2, "\t if the node's variable appears in the fanout's factored form only once\n");
|
Abc_Print( -2, "\t if the node's variable appears in the fanout's factored form only once\n");
|
||||||
Abc_Print( -2, "\t-V <num> : the \"value\" parameter used by \"eliminate\" in SIS [default = %d]\n", ElimValue );
|
Abc_Print( -2, "\t-V <num> : the \"value\" parameter used by \"eliminate\" in SIS [default = %d]\n", ElimValue );
|
||||||
|
|
@ -4009,6 +4017,7 @@ usage:
|
||||||
Abc_Print( -2, "\t-I <num> : the maximum number of iterations [default = %d]\n", nIterMax );
|
Abc_Print( -2, "\t-I <num> : the maximum number of iterations [default = %d]\n", nIterMax );
|
||||||
Abc_Print( -2, "\t-g : toggle using greedy eliminate (without \"value\") [default = %s]\n", fGreedy? "yes": "no" );
|
Abc_Print( -2, "\t-g : toggle using greedy eliminate (without \"value\") [default = %s]\n", fGreedy? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-r : use the reverse topological order [default = %s]\n", fReverse? "yes": "no" );
|
Abc_Print( -2, "\t-r : use the reverse topological order [default = %s]\n", fReverse? "yes": "no" );
|
||||||
|
Abc_Print( -2, "\t-s : toggle eliminating similar nodes [default = %s]\n", fSpecial? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-v : print verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
Abc_Print( -2, "\t-v : print verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue