Commit 9de629ff by Alan Mishchenko

Add command 'splitsop' to split large node SOPs into smaller ones.

parent 00efa680
...@@ -2704,6 +2704,80 @@ void Abc_NtkFromPlaTest() ...@@ -2704,6 +2704,80 @@ void Abc_NtkFromPlaTest()
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_Ntk_t * Abc_NtkSplitSop( Abc_Ntk_t * pNtk, int nCubesMax, int fVerbose )
{
Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin, * pObjNew, * pObjNewRoot;
int i, k, j, nCubes, nCubesThis, nSplits;
char * pSopStr, * pSopStr2, * pTempSop, Symb;
if ( pNtk == NULL )
return NULL;
assert( !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsNetlist(pNtk) );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// copy the internal nodes
vNodes = Abc_NtkDfs( pNtk, 0 );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
{
assert( Abc_ObjIsNode(pObj) );
pObjNewRoot = Abc_NtkDupObj( pNtkNew, pObj, 0 );
nCubes = Abc_SopGetCubeNum( (char *)pObj->pData );
if ( nCubes <= nCubesMax )
{
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
continue;
}
nSplits = (nCubes / nCubesMax) + (int)(nCubes % nCubesMax > 0);
pSopStr = ((char *)pObjNewRoot->pData);
pObjNewRoot->pData = Abc_SopCreateOr(pNtkNew->pManFunc, nSplits, NULL);
if ( Abc_SopIsComplement(pSopStr) )
{
Abc_SopComplement( pSopStr );
Abc_SopComplement( (char *)pObjNewRoot->pData );
}
pTempSop = pObj->pData; pObj->pData = "?";
for ( j = 0; j < nSplits; j++ )
{
// clone the node
pObjNew = Abc_NtkDupObj( pNtkNew, pObj, 0 );
Abc_ObjAddFanin( pObjNewRoot, pObjNew );
// get its cubes
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// create SOP for this node
nCubesThis = (j < nCubes / nCubesMax) ? nCubesMax : nCubes % nCubesMax;
pSopStr2 = pSopStr + (Abc_ObjFaninNum(pObj) + 3) * nCubesThis;
Symb = *pSopStr2; *pSopStr2 = 0;
pObjNew->pData = Abc_SopRegister( pNtkNew->pManFunc, pSopStr );
*pSopStr2 = Symb;
pSopStr = pSopStr2;
}
// update
pObj->pData = pTempSop;
pObj->pCopy = pObjNewRoot;
}
Vec_PtrFree( vNodes );
Abc_NtkFinalize( pNtk, pNtkNew );
// check correctness
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
pNtk->pCopy = pNtkNew;
return pNtkNew;
}
/**Function*************************************************************
Synopsis [Checks if the logic network is in the topological order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkIsTopo( Abc_Ntk_t * pNtk ) int Abc_NtkIsTopo( Abc_Ntk_t * pNtk )
{ {
Abc_Obj_t * pObj, * pFanin; Abc_Obj_t * pObj, * pFanin;
......
...@@ -148,6 +148,7 @@ static int Abc_CommandBidec ( Abc_Frame_t * pAbc, int argc, cha ...@@ -148,6 +148,7 @@ static int Abc_CommandBidec ( Abc_Frame_t * pAbc, int argc, cha
static int Abc_CommandOrder ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandOrder ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMuxes ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCubes ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCubes ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSplitSop ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandExtSeqDcs ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandReach ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandReach ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv );
...@@ -718,6 +719,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) ...@@ -718,6 +719,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Various", "order", Abc_CommandOrder, 0 ); Cmd_CommandAdd( pAbc, "Various", "order", Abc_CommandOrder, 0 );
Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 ); Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 1 );
Cmd_CommandAdd( pAbc, "Various", "cubes", Abc_CommandCubes, 1 ); Cmd_CommandAdd( pAbc, "Various", "cubes", Abc_CommandCubes, 1 );
Cmd_CommandAdd( pAbc, "Various", "splitsop", Abc_CommandSplitSop, 1 );
Cmd_CommandAdd( pAbc, "Various", "ext_seq_dcs", Abc_CommandExtSeqDcs, 0 ); Cmd_CommandAdd( pAbc, "Various", "ext_seq_dcs", Abc_CommandExtSeqDcs, 0 );
Cmd_CommandAdd( pAbc, "Various", "reach", Abc_CommandReach, 0 ); Cmd_CommandAdd( pAbc, "Various", "reach", Abc_CommandReach, 0 );
Cmd_CommandAdd( pAbc, "Various", "cone", Abc_CommandCone, 1 ); Cmd_CommandAdd( pAbc, "Various", "cone", Abc_CommandCone, 1 );
...@@ -8036,6 +8038,82 @@ usage: ...@@ -8036,6 +8038,82 @@ usage:
return 1; return 1;
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandSplitSop( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Abc_Ntk_t * Abc_NtkSplitSop( Abc_Ntk_t * pNtk, int nCubesMax, int fVerbose );
Abc_Ntk_t * pNtk, * pNtkRes;
int c, fVerbose = 0, nCubesMax = 100;
pNtk = Abc_FrameReadNtk(pAbc);
// set defaults
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF )
{
switch ( c )
{
case 'N':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
goto usage;
}
nCubesMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nCubesMax < 0 )
goto usage;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
Abc_Print( -1, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsSopLogic(pNtk) )
{
Abc_Print( -1, "Only a SOP logic network can be transformed into cubes.\n" );
return 1;
}
// get the new network
pNtkRes = Abc_NtkSplitSop( pNtk, nCubesMax, fVerbose );
if ( pNtkRes == NULL )
{
Abc_Print( -1, "Converting to cubes has failed.\n" );
return 1;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
Abc_Print( -2, "usage: splitsop [-N num] [-vh]\n" );
Abc_Print( -2, "\t splits nodes whose SOP size is larger than the given one\n" );
Abc_Print( -2, "\t-N num : the maximum number of cubes after splitting [default = %d]\n", nCubesMax );
Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
/**Function************************************************************* /**Function*************************************************************
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