summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2013-11-23 19:52:00 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2013-11-23 19:52:00 -0800
commit9de629ff59172aba1c7dd55efb303bf41d2ad82c (patch)
tree636bed098eb56f50bb3432bb66f041396414bbb0
parent00efa6805380739f36ca9cc73623aefe25eeb9b5 (diff)
downloadabc-9de629ff59172aba1c7dd55efb303bf41d2ad82c.tar.gz
abc-9de629ff59172aba1c7dd55efb303bf41d2ad82c.tar.bz2
abc-9de629ff59172aba1c7dd55efb303bf41d2ad82c.zip
Add command 'splitsop' to split large node SOPs into smaller ones.
-rw-r--r--src/base/abc/abcUtil.c74
-rw-r--r--src/base/abci/abc.c78
2 files changed, 152 insertions, 0 deletions
diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c
index b3b37da0..faf224dd 100644
--- a/src/base/abc/abcUtil.c
+++ b/src/base/abc/abcUtil.c
@@ -2704,6 +2704,80 @@ void Abc_NtkFromPlaTest()
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 )
{
Abc_Obj_t * pObj, * pFanin;
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index b9be4a18..3804756a 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -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_CommandMuxes ( 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_CommandReach ( 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 )
Cmd_CommandAdd( pAbc, "Various", "order", Abc_CommandOrder, 0 );
Cmd_CommandAdd( pAbc, "Various", "muxes", Abc_CommandMuxes, 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", "reach", Abc_CommandReach, 0 );
Cmd_CommandAdd( pAbc, "Various", "cone", Abc_CommandCone, 1 );
@@ -8036,6 +8038,82 @@ usage:
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*************************************************************