mirror of https://github.com/YosysHQ/abc.git
New MFS package.
This commit is contained in:
parent
8e639c3d79
commit
ed3d3dfc8e
|
|
@ -4475,7 +4475,7 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
// set defaults
|
// set defaults
|
||||||
Sfm_ParSetDefault( pPars );
|
Sfm_ParSetDefault( pPars );
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMNCZdlaevwh" ) ) != EOF )
|
while ( ( c = Extra_UtilGetopt( argc, argv, "WFDMCZdlaevwh" ) ) != EOF )
|
||||||
{
|
{
|
||||||
switch ( c )
|
switch ( c )
|
||||||
{
|
{
|
||||||
|
|
@ -4523,17 +4523,6 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
if ( pPars->nWinSizeMax < 0 )
|
if ( pPars->nWinSizeMax < 0 )
|
||||||
goto usage;
|
goto usage;
|
||||||
break;
|
break;
|
||||||
case 'N':
|
|
||||||
if ( globalUtilOptind >= argc )
|
|
||||||
{
|
|
||||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
|
||||||
goto usage;
|
|
||||||
}
|
|
||||||
pPars->nDivNumMax = atoi(argv[globalUtilOptind]);
|
|
||||||
globalUtilOptind++;
|
|
||||||
if ( pPars->nDivNumMax < 0 )
|
|
||||||
goto usage;
|
|
||||||
break;
|
|
||||||
case 'C':
|
case 'C':
|
||||||
if ( globalUtilOptind >= argc )
|
if ( globalUtilOptind >= argc )
|
||||||
{
|
{
|
||||||
|
|
@ -4590,11 +4579,6 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
Abc_Print( -1, "This command can only be applied to a logic network.\n" );
|
Abc_Print( -1, "This command can only be applied to a logic network.\n" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ( !Abc_NtkIsSopLogic(pNtk) )
|
|
||||||
{
|
|
||||||
Abc_Print( -1, "Currently this command works only for SOP logic networks (run \"sop\").\n" );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// modify the current network
|
// modify the current network
|
||||||
if ( !Abc_NtkPerformMfs( pNtk, pPars ) )
|
if ( !Abc_NtkPerformMfs( pNtk, pPars ) )
|
||||||
{
|
{
|
||||||
|
|
@ -4604,13 +4588,12 @@ int Abc_CommandMfs2( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
Abc_Print( -2, "usage: mfs2 [-WFDMNCZ <num>] [-dlaevwh]\n" );
|
Abc_Print( -2, "usage: mfs2 [-WFDMCZ <num>] [-dlaevwh]\n" );
|
||||||
Abc_Print( -2, "\t performs don't-care-based optimization of logic networks\n" );
|
Abc_Print( -2, "\t performs don't-care-based optimization of logic networks\n" );
|
||||||
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevMax );
|
Abc_Print( -2, "\t-W <num> : the number of levels in the TFO cone (0 <= num) [default = %d]\n", pPars->nTfoLevMax );
|
||||||
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutMax );
|
Abc_Print( -2, "\t-F <num> : the max number of fanouts to skip (1 <= num) [default = %d]\n", pPars->nFanoutMax );
|
||||||
Abc_Print( -2, "\t-D <num> : the max depth nodes to try (0 = no limit) [default = %d]\n", pPars->nDepthMax );
|
Abc_Print( -2, "\t-D <num> : the max depth nodes to try (0 = no limit) [default = %d]\n", pPars->nDepthMax );
|
||||||
Abc_Print( -2, "\t-M <num> : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
|
Abc_Print( -2, "\t-M <num> : the max node count of windows to consider (0 = no limit) [default = %d]\n", pPars->nWinSizeMax );
|
||||||
Abc_Print( -2, "\t-N <num> : the max number of divisors to consider (0 = no limit) [default = %d]\n", pPars->nDivNumMax );
|
|
||||||
Abc_Print( -2, "\t-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit );
|
Abc_Print( -2, "\t-C <num> : the max number of conflicts in one SAT run (0 = no limit) [default = %d]\n", pPars->nBTLimit );
|
||||||
Abc_Print( -2, "\t-Z <num> : treat the first <num> logic nodes as fixed (0 = none) [default = %d]\n", pPars->nFirstFixed );
|
Abc_Print( -2, "\t-Z <num> : treat the first <num> logic nodes as fixed (0 = none) [default = %d]\n", pPars->nFirstFixed );
|
||||||
Abc_Print( -2, "\t-d : toggle performing redundancy removal [default = %s]\n", pPars->fRrOnly? "yes": "no" );
|
Abc_Print( -2, "\t-d : toggle performing redundancy removal [default = %s]\n", pPars->fRrOnly? "yes": "no" );
|
||||||
|
|
|
||||||
|
|
@ -51,16 +51,16 @@ Vec_Ptr_t * Abc_NtkAssignIDs( Abc_Ntk_t * pNtk )
|
||||||
int i;
|
int i;
|
||||||
vNodes = Abc_NtkDfs( pNtk, 0 );
|
vNodes = Abc_NtkDfs( pNtk, 0 );
|
||||||
Abc_NtkCleanCopy( pNtk );
|
Abc_NtkCleanCopy( pNtk );
|
||||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||||
pObj->iTemp = i;
|
pObj->iTemp = i;
|
||||||
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
||||||
{
|
{
|
||||||
pObj->iTemp = Abc_NtkPiNum(pNtk) + i;
|
pObj->iTemp = Abc_NtkCiNum(pNtk) + i;
|
||||||
//printf( "%d->%d ", pObj->Id, pObj->iTemp );
|
//printf( "%d->%d ", pObj->Id, pObj->iTemp );
|
||||||
}
|
}
|
||||||
//printf( "\n" );
|
//printf( "\n" );
|
||||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||||
pObj->iTemp = Abc_NtkPiNum(pNtk) + Vec_PtrSize(vNodes) + i;
|
pObj->iTemp = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes) + i;
|
||||||
return vNodes;
|
return vNodes;
|
||||||
}
|
}
|
||||||
Vec_Ptr_t * Abc_NtkAssignIDs2( Abc_Ntk_t * pNtk )
|
Vec_Ptr_t * Abc_NtkAssignIDs2( Abc_Ntk_t * pNtk )
|
||||||
|
|
@ -69,16 +69,16 @@ Vec_Ptr_t * Abc_NtkAssignIDs2( Abc_Ntk_t * pNtk )
|
||||||
Abc_Obj_t * pObj;
|
Abc_Obj_t * pObj;
|
||||||
int i;
|
int i;
|
||||||
Abc_NtkCleanCopy( pNtk );
|
Abc_NtkCleanCopy( pNtk );
|
||||||
Abc_NtkForEachPi( pNtk, pObj, i )
|
Abc_NtkForEachCi( pNtk, pObj, i )
|
||||||
pObj->iTemp = i;
|
pObj->iTemp = i;
|
||||||
vNodes = Vec_PtrAlloc( Abc_NtkNodeNum(pNtk) );
|
vNodes = Vec_PtrAlloc( Abc_NtkNodeNum(pNtk) );
|
||||||
Abc_NtkForEachNode( pNtk, pObj, i )
|
Abc_NtkForEachNode( pNtk, pObj, i )
|
||||||
{
|
{
|
||||||
Vec_PtrPush( vNodes, pObj );
|
Vec_PtrPush( vNodes, pObj );
|
||||||
pObj->iTemp = Abc_NtkPiNum(pNtk) + i;
|
pObj->iTemp = Abc_NtkCiNum(pNtk) + i;
|
||||||
}
|
}
|
||||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||||
pObj->iTemp = Abc_NtkPiNum(pNtk) + Vec_PtrSize(vNodes) + i;
|
pObj->iTemp = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes) + i;
|
||||||
return vNodes;
|
return vNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,19 +103,22 @@ Sfm_Ntk_t * Abc_NtkExtractMfs( Abc_Ntk_t * pNtk, int nFirstFixed )
|
||||||
Abc_Obj_t * pObj, * pFanin;
|
Abc_Obj_t * pObj, * pFanin;
|
||||||
int i, k, nObjs;
|
int i, k, nObjs;
|
||||||
vNodes = nFirstFixed ? Abc_NtkAssignIDs2(pNtk) : Abc_NtkAssignIDs(pNtk);
|
vNodes = nFirstFixed ? Abc_NtkAssignIDs2(pNtk) : Abc_NtkAssignIDs(pNtk);
|
||||||
nObjs = Abc_NtkPiNum(pNtk) + Vec_PtrSize(vNodes) + Abc_NtkPoNum(pNtk);
|
nObjs = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes) + Abc_NtkCoNum(pNtk);
|
||||||
vFanins = Vec_WecStart( nObjs );
|
vFanins = Vec_WecStart( nObjs );
|
||||||
vFixed = Vec_StrStart( nObjs );
|
vFixed = Vec_StrStart( nObjs );
|
||||||
vTruths = Vec_WrdStart( nObjs );
|
vTruths = Vec_WrdStart( nObjs );
|
||||||
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
|
||||||
{
|
{
|
||||||
|
word uTruth = Abc_SopToTruth((char *)pObj->pData, Abc_ObjFaninNum(pObj));
|
||||||
|
Vec_WrdWriteEntry( vTruths, pObj->iTemp, uTruth );
|
||||||
vArray = Vec_WecEntry( vFanins, pObj->iTemp );
|
vArray = Vec_WecEntry( vFanins, pObj->iTemp );
|
||||||
|
if ( uTruth == 0 || ~uTruth == 0 )
|
||||||
|
continue;
|
||||||
Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
|
Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
|
||||||
Abc_ObjForEachFanin( pObj, pFanin, k )
|
Abc_ObjForEachFanin( pObj, pFanin, k )
|
||||||
Vec_IntPush( vArray, pFanin->iTemp );
|
Vec_IntPush( vArray, pFanin->iTemp );
|
||||||
Vec_WrdWriteEntry( vTruths, pObj->iTemp, Abc_SopToTruth((char *)pObj->pData, Abc_ObjFaninNum(pObj)) );
|
|
||||||
}
|
}
|
||||||
Abc_NtkForEachPo( pNtk, pObj, i )
|
Abc_NtkForEachCo( pNtk, pObj, i )
|
||||||
{
|
{
|
||||||
vArray = Vec_WecEntry( vFanins, pObj->iTemp );
|
vArray = Vec_WecEntry( vFanins, pObj->iTemp );
|
||||||
Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
|
Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
|
||||||
|
|
@ -125,9 +128,9 @@ Sfm_Ntk_t * Abc_NtkExtractMfs( Abc_Ntk_t * pNtk, int nFirstFixed )
|
||||||
Vec_PtrFree( vNodes );
|
Vec_PtrFree( vNodes );
|
||||||
// update fixed
|
// update fixed
|
||||||
assert( nFirstFixed >= 0 && nFirstFixed < Abc_NtkNodeNum(pNtk) );
|
assert( nFirstFixed >= 0 && nFirstFixed < Abc_NtkNodeNum(pNtk) );
|
||||||
for ( i = Abc_NtkPiNum(pNtk); i < Abc_NtkPiNum(pNtk) + nFirstFixed; i++ )
|
for ( i = Abc_NtkCiNum(pNtk); i < Abc_NtkCiNum(pNtk) + nFirstFixed; i++ )
|
||||||
Vec_StrWriteEntry( vFixed, i, (char)1 );
|
Vec_StrWriteEntry( vFixed, i, (char)1 );
|
||||||
return Sfm_NtkConstruct( vFanins, Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk), vFixed, vTruths );
|
return Sfm_NtkConstruct( vFanins, Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), vFixed, vTruths );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**Function*************************************************************
|
/**Function*************************************************************
|
||||||
|
|
@ -150,7 +153,7 @@ void Abc_NtkInsertMfs( Abc_Ntk_t * pNtk, Sfm_Ntk_t * p )
|
||||||
word * pTruth;
|
word * pTruth;
|
||||||
// map new IDs into old nodes
|
// map new IDs into old nodes
|
||||||
vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
|
||||||
Abc_NtkForEachPi( pNtk, pNode, i )
|
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||||
Vec_IntWriteEntry( vMap, pNode->iTemp, Abc_ObjId(pNode) );
|
Vec_IntWriteEntry( vMap, pNode->iTemp, Abc_ObjId(pNode) );
|
||||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||||
if ( pNode->iTemp > 0 )
|
if ( pNode->iTemp > 0 )
|
||||||
|
|
@ -180,13 +183,14 @@ void Abc_NtkInsertMfs( Abc_Ntk_t * pNtk, Sfm_Ntk_t * p )
|
||||||
pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" );
|
pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// pNode->pData = Abc_SopCreateFromTruth( (Mem_Flex_t *)pNtk->pManFunc, Vec_IntSize(vArray), (unsigned *)pTruth );
|
|
||||||
int RetValue = Kit_TruthIsop( (unsigned *)pTruth, Vec_IntSize(vArray), vCover, 1 );
|
int RetValue = Kit_TruthIsop( (unsigned *)pTruth, Vec_IntSize(vArray), vCover, 1 );
|
||||||
|
assert( Vec_IntSize(vArray) > 0 );
|
||||||
assert( RetValue == 0 || RetValue == 1 );
|
assert( RetValue == 0 || RetValue == 1 );
|
||||||
pNode->pData = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtk->pManFunc, Vec_IntSize(vArray), vCover );
|
pNode->pData = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtk->pManFunc, Vec_IntSize(vArray), vCover );
|
||||||
if ( RetValue )
|
if ( RetValue )
|
||||||
Abc_SopComplement( (char *)pNode->pData );
|
Abc_SopComplement( (char *)pNode->pData );
|
||||||
}
|
}
|
||||||
|
assert( Abc_SopGetVarNum((char *)pNode->pData) == Vec_IntSize(vArray) );
|
||||||
}
|
}
|
||||||
Vec_IntFree( vMap );
|
Vec_IntFree( vMap );
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +210,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
|
||||||
{
|
{
|
||||||
Sfm_Ntk_t * p;
|
Sfm_Ntk_t * p;
|
||||||
int nFaninMax, nNodes;
|
int nFaninMax, nNodes;
|
||||||
assert( Abc_NtkIsSopLogic(pNtk) );
|
assert( Abc_NtkIsLogic(pNtk) );
|
||||||
// count fanouts
|
// count fanouts
|
||||||
nFaninMax = Abc_NtkGetFaninMax( pNtk );
|
nFaninMax = Abc_NtkGetFaninMax( pNtk );
|
||||||
if ( nFaninMax > 6 )
|
if ( nFaninMax > 6 )
|
||||||
|
|
@ -214,6 +218,8 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
|
||||||
Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" );
|
Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 6 fanins.\n" );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if ( !Abc_NtkHasSop(pNtk) )
|
||||||
|
Abc_NtkToSop( pNtk, 0 );
|
||||||
// collect information
|
// collect information
|
||||||
p = Abc_NtkExtractMfs( pNtk, pPars->nFirstFixed );
|
p = Abc_NtkExtractMfs( pNtk, pPars->nFirstFixed );
|
||||||
// perform optimization
|
// perform optimization
|
||||||
|
|
@ -224,6 +230,7 @@ int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Abc_NtkInsertMfs( pNtk, p );
|
Abc_NtkInsertMfs( pNtk, p );
|
||||||
|
if( pPars->fVerbose )
|
||||||
Abc_Print( 1, "The network has %d nodes changed by \"mfs\".\n", nNodes );
|
Abc_Print( 1, "The network has %d nodes changed by \"mfs\".\n", nNodes );
|
||||||
}
|
}
|
||||||
Sfm_NtkFree( p );
|
Sfm_NtkFree( p );
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,8 @@ void Mfs_ManPrint( Mfs_Man_t * p )
|
||||||
printf( "\n" );
|
printf( "\n" );
|
||||||
|
|
||||||
printf( "Reduction: " );
|
printf( "Reduction: " );
|
||||||
printf( "Nodes %6d out of %6d (%6.2f %%) ", p->nTotalNodesBeg-p->nTotalNodesEnd, p->nTotalNodesEnd, 100.0*(p->nTotalNodesBeg-p->nTotalNodesEnd)/Abc_MaxInt(1, p->nTotalNodesBeg) );
|
printf( "Nodes %6d out of %6d (%6.2f %%) ", p->nTotalNodesBeg-p->nTotalNodesEnd, p->nTotalNodesBeg, 100.0*(p->nTotalNodesBeg-p->nTotalNodesEnd)/Abc_MaxInt(1, p->nTotalNodesBeg) );
|
||||||
printf( "Edges %6d out of %6d (%6.2f %%) ", p->nTotalEdgesBeg-p->nTotalEdgesEnd, p->nTotalEdgesEnd, 100.0*(p->nTotalEdgesBeg-p->nTotalEdgesEnd)/Abc_MaxInt(1, p->nTotalEdgesBeg) );
|
printf( "Edges %6d out of %6d (%6.2f %%) ", p->nTotalEdgesBeg-p->nTotalEdgesEnd, p->nTotalEdgesBeg, 100.0*(p->nTotalEdgesBeg-p->nTotalEdgesEnd)/Abc_MaxInt(1, p->nTotalEdgesBeg) );
|
||||||
printf( "\n" );
|
printf( "\n" );
|
||||||
|
|
||||||
if (p->pPars->fPower)
|
if (p->pPars->fPower)
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,6 @@ struct Sfm_Par_t_
|
||||||
int nFanoutMax; // the maximum number of fanouts
|
int nFanoutMax; // the maximum number of fanouts
|
||||||
int nDepthMax; // the maximum depth to try
|
int nDepthMax; // the maximum depth to try
|
||||||
int nWinSizeMax; // the maximum window size
|
int nWinSizeMax; // the maximum window size
|
||||||
int nDivNumMax; // the maximum number of divisors
|
|
||||||
int nBTLimit; // the maximum number of conflicts in one SAT run
|
int nBTLimit; // the maximum number of conflicts in one SAT run
|
||||||
int nFirstFixed; // the number of first nodes to be treated as fixed
|
int nFirstFixed; // the number of first nodes to be treated as fixed
|
||||||
int fFixLevel; // does not allow level to increase
|
int fFixLevel; // does not allow level to increase
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ int Sfm_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf
|
||||||
Vec_StrClear( vCnf );
|
Vec_StrClear( vCnf );
|
||||||
if ( Truth == 0 || ~Truth == 0 )
|
if ( Truth == 0 || ~Truth == 0 )
|
||||||
{
|
{
|
||||||
|
// assert( nVars == 0 );
|
||||||
Vec_StrPush( vCnf, (char)(Truth == 0) );
|
Vec_StrPush( vCnf, (char)(Truth == 0) );
|
||||||
Vec_StrPush( vCnf, (char)-1 );
|
Vec_StrPush( vCnf, (char)-1 );
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -80,6 +81,7 @@ int Sfm_TruthToCnf( word Truth, int nVars, Vec_Int_t * vCover, Vec_Str_t * vCnf
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i, k, c, RetValue, Literal, Cube, nCubes = 0;
|
int i, k, c, RetValue, Literal, Cube, nCubes = 0;
|
||||||
|
assert( nVars > 0 );
|
||||||
for ( c = 0; c < 2; c ++ )
|
for ( c = 0; c < 2; c ++ )
|
||||||
{
|
{
|
||||||
Truth = c ? ~Truth : Truth;
|
Truth = c ? ~Truth : Truth;
|
||||||
|
|
@ -159,10 +161,8 @@ void Sfm_TranslateCnf( Vec_Wec_t * vRes, Vec_Str_t * vCnf, Vec_Int_t * vFaninMap
|
||||||
{
|
{
|
||||||
Lit = (int)Entry;
|
Lit = (int)Entry;
|
||||||
if ( Lit == -1 )
|
if ( Lit == -1 )
|
||||||
{
|
|
||||||
vClause = Vec_WecPushLevel( vRes );
|
vClause = Vec_WecPushLevel( vRes );
|
||||||
continue;
|
else
|
||||||
}
|
|
||||||
Vec_IntPush( vClause, Abc_Lit2LitV( Vec_IntArray(vFaninMap), Lit ) );
|
Vec_IntPush( vClause, Abc_Lit2LitV( Vec_IntArray(vFaninMap), Lit ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ void Sfm_ParSetDefault( Sfm_Par_t * pPars )
|
||||||
pPars->nFanoutMax = 30; // the maximum number of fanouts
|
pPars->nFanoutMax = 30; // the maximum number of fanouts
|
||||||
pPars->nDepthMax = 20; // the maximum depth to try
|
pPars->nDepthMax = 20; // the maximum depth to try
|
||||||
pPars->nWinSizeMax = 300; // the maximum window size
|
pPars->nWinSizeMax = 300; // the maximum window size
|
||||||
pPars->nDivNumMax = 300; // the maximum number of divisors
|
|
||||||
pPars->nBTLimit = 0; // the maximum number of conflicts in one SAT run
|
pPars->nBTLimit = 0; // the maximum number of conflicts in one SAT run
|
||||||
pPars->fFixLevel = 1; // does not allow level to increase
|
pPars->fFixLevel = 1; // does not allow level to increase
|
||||||
pPars->fRrOnly = 0; // perform redundancy removal
|
pPars->fRrOnly = 0; // perform redundancy removal
|
||||||
|
|
@ -82,8 +81,8 @@ void Sfm_NtkPrintStats( Sfm_Ntk_t * p )
|
||||||
printf( "\n" );
|
printf( "\n" );
|
||||||
|
|
||||||
printf( "Reduction: " );
|
printf( "Reduction: " );
|
||||||
printf( "Nodes %6d out of %6d (%6.2f %%) ", p->nTotalNodesBeg-p->nTotalNodesEnd, p->nTotalNodesEnd, 100.0*(p->nTotalNodesBeg-p->nTotalNodesEnd)/Abc_MaxInt(1, p->nTotalNodesBeg) );
|
printf( "Nodes %6d out of %6d (%6.2f %%) ", p->nTotalNodesBeg-p->nTotalNodesEnd, p->nTotalNodesBeg, 100.0*(p->nTotalNodesBeg-p->nTotalNodesEnd)/Abc_MaxInt(1, p->nTotalNodesBeg) );
|
||||||
printf( "Edges %6d out of %6d (%6.2f %%) ", p->nTotalEdgesBeg-p->nTotalEdgesEnd, p->nTotalEdgesEnd, 100.0*(p->nTotalEdgesBeg-p->nTotalEdgesEnd)/Abc_MaxInt(1, p->nTotalEdgesBeg) );
|
printf( "Edges %6d out of %6d (%6.2f %%) ", p->nTotalEdgesBeg-p->nTotalEdgesEnd, p->nTotalEdgesBeg, 100.0*(p->nTotalEdgesBeg-p->nTotalEdgesEnd)/Abc_MaxInt(1, p->nTotalEdgesBeg) );
|
||||||
printf( "\n" );
|
printf( "\n" );
|
||||||
|
|
||||||
ABC_PRTP( "Win", p->timeWin , p->timeTotal );
|
ABC_PRTP( "Win", p->timeWin , p->timeTotal );
|
||||||
|
|
@ -254,14 +253,14 @@ int Sfm_NodeResub( Sfm_Ntk_t * p, int iNode )
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
int Sfm_NtkPerform( Sfm_Ntk_t * p, Sfm_Par_t * pPars )
|
int Sfm_NtkPerform( Sfm_Ntk_t * p, Sfm_Par_t * pPars )
|
||||||
{
|
{
|
||||||
int i, Counter = 0;
|
int i, k, Counter = 0;
|
||||||
p->timeTotal = clock();
|
p->timeTotal = clock();
|
||||||
p->pPars = pPars;
|
p->pPars = pPars;
|
||||||
Sfm_NtkPrepare( p );
|
Sfm_NtkPrepare( p );
|
||||||
// Sfm_ComputeInterpolantCheck( p );
|
// Sfm_ComputeInterpolantCheck( p );
|
||||||
// return 0;
|
// return 0;
|
||||||
p->nTotalNodesBeg = Vec_WecSizeUsed(&p->vFanins) - Sfm_NtkPoNum(p);
|
p->nTotalNodesBeg = Vec_WecSize(&p->vFanins) - Sfm_NtkPiNum(p) - Sfm_NtkPoNum(p);
|
||||||
p->nTotalEdgesBeg = Vec_WecSizeSize(&p->vFanins);
|
p->nTotalEdgesBeg = Vec_WecSizeSize(&p->vFanins) - Sfm_NtkPoNum(p);
|
||||||
Sfm_NtkForEachNode( p, i )
|
Sfm_NtkForEachNode( p, i )
|
||||||
{
|
{
|
||||||
if ( Sfm_ObjIsFixed( p, i ) )
|
if ( Sfm_ObjIsFixed( p, i ) )
|
||||||
|
|
@ -270,11 +269,12 @@ int Sfm_NtkPerform( Sfm_Ntk_t * p, Sfm_Par_t * pPars )
|
||||||
continue;
|
continue;
|
||||||
if ( Sfm_ObjFaninNum(p, i) < 2 || Sfm_ObjFaninNum(p, i) > 6 )
|
if ( Sfm_ObjFaninNum(p, i) < 2 || Sfm_ObjFaninNum(p, i) > 6 )
|
||||||
continue;
|
continue;
|
||||||
while ( Sfm_NodeResub(p, i) )
|
for ( k = 0; Sfm_NodeResub(p, i); k++ )
|
||||||
Counter++;
|
;
|
||||||
|
Counter += (k > 0);
|
||||||
}
|
}
|
||||||
p->nTotalNodesEnd = Vec_WecSizeUsed(&p->vFanins) - Sfm_NtkPoNum(p);
|
p->nTotalNodesEnd = Vec_WecSizeUsed(&p->vFanins) - Sfm_NtkPoNum(p);
|
||||||
p->nTotalEdgesEnd = Vec_WecSizeSize(&p->vFanins);
|
p->nTotalEdgesEnd = Vec_WecSizeSize(&p->vFanins) - Sfm_NtkPoNum(p);
|
||||||
p->timeTotal = clock() - p->timeTotal;
|
p->timeTotal = clock() - p->timeTotal;
|
||||||
if ( pPars->fVerbose )
|
if ( pPars->fVerbose )
|
||||||
Sfm_NtkPrintStats( p );
|
Sfm_NtkPrintStats( p );
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ void Sfm_NtkPrepare( Sfm_Ntk_t * p )
|
||||||
p->vDivs = Vec_IntAlloc( 100 );
|
p->vDivs = Vec_IntAlloc( 100 );
|
||||||
p->vRoots = Vec_IntAlloc( 1000 );
|
p->vRoots = Vec_IntAlloc( 1000 );
|
||||||
p->vTfo = Vec_IntAlloc( 1000 );
|
p->vTfo = Vec_IntAlloc( 1000 );
|
||||||
p->vDivCexes = Vec_WrdStart( p->pPars->nDivNumMax );
|
p->vDivCexes = Vec_WrdStart( p->pPars->nWinSizeMax );
|
||||||
p->vOrder = Vec_IntAlloc( 100 );
|
p->vOrder = Vec_IntAlloc( 100 );
|
||||||
p->vDivVars = Vec_IntAlloc( 100 );
|
p->vDivVars = Vec_IntAlloc( 100 );
|
||||||
p->vDivIds = Vec_IntAlloc( 1000 );
|
p->vDivIds = Vec_IntAlloc( 1000 );
|
||||||
|
|
@ -177,6 +177,7 @@ void Sfm_NtkPrepare( Sfm_Ntk_t * p )
|
||||||
p->vClauses = Vec_WecAlloc( 100 );
|
p->vClauses = Vec_WecAlloc( 100 );
|
||||||
p->vFaninMap = Vec_IntAlloc( 10 );
|
p->vFaninMap = Vec_IntAlloc( 10 );
|
||||||
p->pSat = sat_solver_new();
|
p->pSat = sat_solver_new();
|
||||||
|
sat_solver_setnvars( p->pSat, p->pPars->nWinSizeMax );
|
||||||
}
|
}
|
||||||
void Sfm_NtkFree( Sfm_Ntk_t * p )
|
void Sfm_NtkFree( Sfm_Ntk_t * p )
|
||||||
{
|
{
|
||||||
|
|
@ -226,6 +227,8 @@ void Sfm_NtkFree( Sfm_Ntk_t * p )
|
||||||
void Sfm_NtkRemoveFanin( Sfm_Ntk_t * p, int iNode, int iFanin )
|
void Sfm_NtkRemoveFanin( Sfm_Ntk_t * p, int iNode, int iFanin )
|
||||||
{
|
{
|
||||||
int RetValue;
|
int RetValue;
|
||||||
|
assert( Sfm_ObjIsNode(p, iNode) );
|
||||||
|
assert( !Sfm_ObjIsPo(p, iFanin) );
|
||||||
RetValue = Vec_IntRemove( Sfm_ObjFiArray(p, iNode), iFanin );
|
RetValue = Vec_IntRemove( Sfm_ObjFiArray(p, iNode), iFanin );
|
||||||
assert( RetValue );
|
assert( RetValue );
|
||||||
RetValue = Vec_IntRemove( Sfm_ObjFoArray(p, iFanin), iNode );
|
RetValue = Vec_IntRemove( Sfm_ObjFoArray(p, iFanin), iNode );
|
||||||
|
|
@ -235,6 +238,8 @@ void Sfm_NtkAddFanin( Sfm_Ntk_t * p, int iNode, int iFanin )
|
||||||
{
|
{
|
||||||
if ( iFanin < 0 )
|
if ( iFanin < 0 )
|
||||||
return;
|
return;
|
||||||
|
assert( Sfm_ObjIsNode(p, iNode) );
|
||||||
|
assert( !Sfm_ObjIsPo(p, iFanin) );
|
||||||
assert( Vec_IntFind( Sfm_ObjFiArray(p, iNode), iFanin ) == -1 );
|
assert( Vec_IntFind( Sfm_ObjFiArray(p, iNode), iFanin ) == -1 );
|
||||||
assert( Vec_IntFind( Sfm_ObjFoArray(p, iFanin), iNode ) == -1 );
|
assert( Vec_IntFind( Sfm_ObjFoArray(p, iFanin), iNode ) == -1 );
|
||||||
Vec_IntPush( Sfm_ObjFiArray(p, iNode), iFanin );
|
Vec_IntPush( Sfm_ObjFiArray(p, iNode), iFanin );
|
||||||
|
|
@ -268,13 +273,26 @@ void Sfm_NtkUpdateLevel_rec( Sfm_Ntk_t * p, int iNode )
|
||||||
void Sfm_NtkUpdate( Sfm_Ntk_t * p, int iNode, int f, int iFaninNew, word uTruth )
|
void Sfm_NtkUpdate( Sfm_Ntk_t * p, int iNode, int f, int iFaninNew, word uTruth )
|
||||||
{
|
{
|
||||||
int iFanin = Sfm_ObjFanin( p, iNode, f );
|
int iFanin = Sfm_ObjFanin( p, iNode, f );
|
||||||
assert( iFanin != iFaninNew );
|
|
||||||
// replace old fanin by new fanin
|
|
||||||
assert( Sfm_ObjIsNode(p, iNode) );
|
assert( Sfm_ObjIsNode(p, iNode) );
|
||||||
|
assert( iFanin != iFaninNew );
|
||||||
|
if ( uTruth == 0 || ~uTruth == 0 )
|
||||||
|
{
|
||||||
|
Sfm_ObjForEachFanin( p, iNode, iFanin, f )
|
||||||
|
{
|
||||||
|
int RetValue = Vec_IntRemove( Sfm_ObjFoArray(p, iFanin), iNode ); assert( RetValue );
|
||||||
|
if ( Sfm_ObjFanoutNum(p, iFanin) == 0 )
|
||||||
|
Sfm_NtkDeleteObj_rec( p, iFanin );
|
||||||
|
}
|
||||||
|
Vec_IntClear( Sfm_ObjFiArray(p, iNode) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// replace old fanin by new fanin
|
||||||
Sfm_NtkRemoveFanin( p, iNode, iFanin );
|
Sfm_NtkRemoveFanin( p, iNode, iFanin );
|
||||||
Sfm_NtkAddFanin( p, iNode, iFaninNew );
|
Sfm_NtkAddFanin( p, iNode, iFaninNew );
|
||||||
// recursively remove MFFC
|
// recursively remove MFFC
|
||||||
Sfm_NtkDeleteObj_rec( p, iFanin );
|
Sfm_NtkDeleteObj_rec( p, iFanin );
|
||||||
|
}
|
||||||
// update logic level
|
// update logic level
|
||||||
Sfm_NtkUpdateLevel_rec( p, iNode );
|
Sfm_NtkUpdateLevel_rec( p, iNode );
|
||||||
// update truth table
|
// update truth table
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ void Sfm_NtkWindowToSolver( Sfm_Ntk_t * p )
|
||||||
// if ( p->pSat )
|
// if ( p->pSat )
|
||||||
// printf( "%d ", p->pSat->stats.learnts );
|
// printf( "%d ", p->pSat->stats.learnts );
|
||||||
sat_solver_restart( p->pSat );
|
sat_solver_restart( p->pSat );
|
||||||
sat_solver_setnvars( p->pSat, 1 + Vec_IntSize(p->vDivs) + 2 * Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots) + 100 );
|
sat_solver_setnvars( p->pSat, 1 + Vec_IntSize(p->vDivs) + 2 * Vec_IntSize(p->vTfo) + Vec_IntSize(p->vRoots) + 50 );
|
||||||
// create SAT variables
|
// create SAT variables
|
||||||
Sfm_NtkCleanVars( p );
|
Sfm_NtkCleanVars( p );
|
||||||
p->nSatVars = 1;
|
p->nSatVars = 1;
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ void Sfm_NtkAddDivisors( Sfm_Ntk_t * p, int iNode, int nLevelMax )
|
||||||
if ( p->pPars->nFanoutMax && i > p->pPars->nFanoutMax )
|
if ( p->pPars->nFanoutMax && i > p->pPars->nFanoutMax )
|
||||||
break;
|
break;
|
||||||
// skip TFI nodes, PO nodes, or nodes with high logic level
|
// skip TFI nodes, PO nodes, or nodes with high logic level
|
||||||
if ( Sfm_ObjIsTravIdCurrent(p, iFanout) || Sfm_ObjIsPo(p, iFanout) ||
|
if ( Sfm_ObjIsTravIdCurrent(p, iFanout) || Sfm_ObjIsPo(p, iFanout) || Sfm_ObjIsFixed(p, iFanout) ||
|
||||||
(p->pPars->fFixLevel && Sfm_ObjLevel(p, iFanout) >= nLevelMax) )
|
(p->pPars->fFixLevel && Sfm_ObjLevel(p, iFanout) >= nLevelMax) )
|
||||||
continue;
|
continue;
|
||||||
// handle single-input nodes
|
// handle single-input nodes
|
||||||
|
|
@ -241,7 +241,7 @@ int Sfm_NtkCollectTfi_rec( Sfm_Ntk_t * p, int iNode, int nWinSizeMax )
|
||||||
}
|
}
|
||||||
int Sfm_NtkCreateWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
|
int Sfm_NtkCreateWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
|
||||||
{
|
{
|
||||||
int i, iTemp;
|
int i, k, iTemp, nDivStart;
|
||||||
clock_t clk = clock();
|
clock_t clk = clock();
|
||||||
assert( Sfm_ObjIsNode( p, iNode ) );
|
assert( Sfm_ObjIsNode( p, iNode ) );
|
||||||
Vec_IntClear( p->vLeaves ); // leaves
|
Vec_IntClear( p->vLeaves ); // leaves
|
||||||
|
|
@ -272,56 +272,47 @@ int Sfm_NtkCreateWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
|
||||||
Vec_IntPush( p->vRoots, iNode );
|
Vec_IntPush( p->vRoots, iNode );
|
||||||
p->timeWin += clock() - clk;
|
p->timeWin += clock() - clk;
|
||||||
clk = clock();
|
clk = clock();
|
||||||
|
// create divisors
|
||||||
|
Vec_IntClear( p->vDivs );
|
||||||
|
Vec_IntForEachEntry( p->vLeaves, iTemp, i )
|
||||||
|
Vec_IntPush( p->vDivs, iTemp );
|
||||||
|
Vec_IntForEachEntry( p->vNodes, iTemp, i )
|
||||||
|
Vec_IntPush( p->vDivs, iTemp );
|
||||||
|
Vec_IntPop( p->vDivs );
|
||||||
|
// add non-topological divisors
|
||||||
|
nDivStart = Vec_IntSize(p->vDivs);
|
||||||
|
if ( Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax )
|
||||||
|
{
|
||||||
|
Sfm_NtkIncrementTravId2( p );
|
||||||
|
Vec_IntForEachEntry( p->vDivs, iTemp, i )
|
||||||
|
if ( Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax )
|
||||||
|
Sfm_NtkAddDivisors( p, iTemp, Sfm_ObjLevel(p, iNode) );
|
||||||
|
}
|
||||||
|
if ( Vec_IntSize(p->vDivs) > p->pPars->nWinSizeMax )
|
||||||
|
Vec_IntShrink( p->vDivs, p->pPars->nWinSizeMax );
|
||||||
|
assert( Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
|
||||||
|
p->nMaxDivs += (Vec_IntSize(p->vDivs) == p->pPars->nWinSizeMax);
|
||||||
// create ordering of the nodes
|
// create ordering of the nodes
|
||||||
Vec_IntClear( p->vOrder );
|
Vec_IntClear( p->vOrder );
|
||||||
Vec_IntForEachEntryReverse( p->vNodes, iTemp, i )
|
Vec_IntForEachEntryReverse( p->vNodes, iTemp, i )
|
||||||
Vec_IntPush( p->vOrder, iTemp );
|
Vec_IntPush( p->vOrder, iTemp );
|
||||||
Vec_IntForEachEntry( p->vLeaves, iTemp, i )
|
Vec_IntForEachEntry( p->vLeaves, iTemp, i )
|
||||||
Vec_IntPush( p->vOrder, iTemp );
|
Vec_IntPush( p->vOrder, iTemp );
|
||||||
|
Vec_IntForEachEntryStart( p->vDivs, iTemp, i, nDivStart )
|
||||||
|
Vec_IntPush( p->vOrder, iTemp );
|
||||||
|
// remove fanins from divisors
|
||||||
// mark fanins
|
// mark fanins
|
||||||
Sfm_NtkIncrementTravId2( p );
|
Sfm_NtkIncrementTravId2( p );
|
||||||
Sfm_ObjSetTravIdCurrent2( p, iNode );
|
Sfm_ObjSetTravIdCurrent2( p, iNode );
|
||||||
Sfm_ObjForEachFanin( p, iNode, iTemp, i )
|
Sfm_ObjForEachFanin( p, iNode, iTemp, i )
|
||||||
Sfm_ObjSetTravIdCurrent2( p, iTemp );
|
Sfm_ObjSetTravIdCurrent2( p, iTemp );
|
||||||
// compact divisors
|
// compact divisors
|
||||||
Vec_IntClear( p->vDivs );
|
k = 0;
|
||||||
Vec_IntForEachEntry( p->vLeaves, iTemp, i )
|
Vec_IntForEachEntry( p->vDivs, iTemp, i )
|
||||||
if ( !Sfm_ObjIsTravIdCurrent2( p, iTemp ) )
|
if ( !Sfm_ObjIsTravIdCurrent2( p, iTemp ) )
|
||||||
Vec_IntPush( p->vDivs, iTemp );
|
|
||||||
Vec_IntForEachEntry( p->vNodes, iTemp, i )
|
|
||||||
if ( !Sfm_ObjIsTravIdCurrent2( p, iTemp ) )
|
|
||||||
Vec_IntPush( p->vDivs, iTemp );
|
|
||||||
// if we exceed the limit, remove the first few
|
|
||||||
if ( Vec_IntSize(p->vDivs) > p->pPars->nDivNumMax )
|
|
||||||
{
|
|
||||||
int k = 0;
|
|
||||||
Vec_IntForEachEntryStart( p->vDivs, iTemp, i, Vec_IntSize(p->vDivs) - p->pPars->nDivNumMax )
|
|
||||||
Vec_IntWriteEntry( p->vDivs, k++, iTemp );
|
Vec_IntWriteEntry( p->vDivs, k++, iTemp );
|
||||||
Vec_IntShrink( p->vDivs, k );
|
Vec_IntShrink( p->vDivs, k );
|
||||||
assert( Vec_IntSize(p->vDivs) == p->pPars->nDivNumMax );
|
assert( Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
|
||||||
}
|
|
||||||
//Vec_IntPrint( p->vLeaves );
|
|
||||||
//Vec_IntPrint( p->vNodes );
|
|
||||||
//Vec_IntPrint( p->vDivs );
|
|
||||||
// collect additional divisors of the TFI nodes
|
|
||||||
if ( Vec_IntSize(p->vDivs) < p->pPars->nDivNumMax )
|
|
||||||
{
|
|
||||||
int nStartNew = Vec_IntSize(p->vDivs);
|
|
||||||
Sfm_NtkIncrementTravId2( p );
|
|
||||||
Sfm_ObjForEachFanin( p, iNode, iTemp, i )
|
|
||||||
if ( Vec_IntSize(p->vDivs) < p->pPars->nDivNumMax )
|
|
||||||
Sfm_NtkAddDivisors( p, iTemp, Sfm_ObjLevel(p, iNode) );
|
|
||||||
Vec_IntForEachEntry( p->vDivs, iTemp, i )
|
|
||||||
if ( Vec_IntSize(p->vDivs) < p->pPars->nDivNumMax )
|
|
||||||
Sfm_NtkAddDivisors( p, iTemp, Sfm_ObjLevel(p, iNode) );
|
|
||||||
if ( Vec_IntSize(p->vDivs) > p->pPars->nDivNumMax )
|
|
||||||
Vec_IntShrink( p->vDivs, p->pPars->nDivNumMax );
|
|
||||||
// add new divisor variable to the order
|
|
||||||
Vec_IntForEachEntryStart( p->vDivs, iTemp, i, nStartNew )
|
|
||||||
Vec_IntPush( p->vOrder, iTemp );
|
|
||||||
}
|
|
||||||
assert( Vec_IntSize(p->vDivs) <= p->pPars->nDivNumMax );
|
|
||||||
p->nMaxDivs += (Vec_IntSize(p->vDivs) == p->pPars->nDivNumMax);
|
|
||||||
// statistics
|
// statistics
|
||||||
p->nTotalDivs += Vec_IntSize(p->vDivs);
|
p->nTotalDivs += Vec_IntSize(p->vDivs);
|
||||||
p->timeDiv += clock() - clk;
|
p->timeDiv += clock() - clk;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue