diff options
-rw-r--r-- | src/base/abc/abc.h | 1 | ||||
-rw-r--r-- | src/base/abc/abcFunc.c | 8 | ||||
-rw-r--r-- | src/base/io/io.c | 12 | ||||
-rw-r--r-- | src/base/io/ioAbc.h | 2 | ||||
-rw-r--r-- | src/base/io/ioUtil.c | 6 | ||||
-rw-r--r-- | src/base/io/ioWritePla.c | 326 |
6 files changed, 308 insertions, 47 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index d684d3df..c23a711a 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -258,6 +258,7 @@ static inline int Abc_NtkHasBlifMv( Abc_Ntk_t * pNtk ) { return pN static inline int Abc_NtkHasBlackbox( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLACKBOX; } static inline int Abc_NtkIsSopNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_SOP && pNtk->ntkType == ABC_NTK_NETLIST; } +static inline int Abc_NtkIsBddNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BDD && pNtk->ntkType == ABC_NTK_NETLIST; } static inline int Abc_NtkIsAigNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_AIG && pNtk->ntkType == ABC_NTK_NETLIST; } static inline int Abc_NtkIsMappedNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_MAP && pNtk->ntkType == ABC_NTK_NETLIST; } static inline int Abc_NtkIsBlifMvNetlist( Abc_Ntk_t * pNtk ) { return pNtk->ntkFunc == ABC_FUNC_BLIFMV && pNtk->ntkType == ABC_NTK_NETLIST; } diff --git a/src/base/abc/abcFunc.c b/src/base/abc/abcFunc.c index d7b22b04..782091d7 100644 --- a/src/base/abc/abcFunc.c +++ b/src/base/abc/abcFunc.c @@ -30,7 +30,7 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define ABC_MUX_CUBES 100000 +#define ABC_MAX_CUBES 100000 int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase ); static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot); @@ -307,10 +307,10 @@ char * Abc_ConvertBddToSop( Mem_Flex_t * pMan, DdManager * dd, DdNode * bFuncOn, assert( 0 ); } - if ( nCubes > ABC_MUX_CUBES ) + if ( nCubes > ABC_MAX_CUBES ) { Cudd_RecursiveDerefZdd( dd, zCover ); - printf( "The number of cubes exceeded the predefined limit (%d).\n", ABC_MUX_CUBES ); + printf( "The number of cubes exceeded the predefined limit (%d).\n", ABC_MAX_CUBES ); return NULL; } @@ -571,7 +571,7 @@ void Abc_CountZddCubes_rec( DdManager * dd, DdNode * zCover, int * pnCubes ) (*pnCubes)++; return; } - if ( (*pnCubes) > ABC_MUX_CUBES ) + if ( (*pnCubes) > ABC_MAX_CUBES ) return; extraDecomposeCover( dd, zCover, &zC0, &zC1, &zC2 ); Abc_CountZddCubes_rec( dd, zC0, pnCubes ); diff --git a/src/base/io/io.c b/src/base/io/io.c index 746a7285..bf01c7b5 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -2479,13 +2479,16 @@ usage: int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) { char * pFileName; - int c; + int c, fUseMoPla = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "mh" ) ) != EOF ) { switch ( c ) { + case 'm': + fUseMoPla ^= 1; + break; case 'h': goto usage; default: @@ -2502,12 +2505,13 @@ int IoCommandWritePla( Abc_Frame_t * pAbc, int argc, char **argv ) // get the output file name pFileName = argv[globalUtilOptind]; // call the corresponding file writer - Io_Write( pAbc->pNtkCur, pFileName, IO_FILE_PLA ); + Io_Write( pAbc->pNtkCur, pFileName, fUseMoPla ? IO_FILE_MOPLA : IO_FILE_PLA ); return 0; usage: - fprintf( pAbc->Err, "usage: write_pla [-h] <file>\n" ); + fprintf( pAbc->Err, "usage: write_pla [-mh] <file>\n" ); fprintf( pAbc->Err, "\t writes the collapsed network into a PLA file\n" ); + fprintf( pAbc->Err, "\t-m : toggle writing multi-output PLA [default = %s]\n", fUseMoPla? "yes":"no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); return 1; diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h index f20f5c3d..39eec63d 100644 --- a/src/base/io/ioAbc.h +++ b/src/base/io/ioAbc.h @@ -59,6 +59,7 @@ typedef enum { IO_FILE_GML, IO_FILE_LIST, IO_FILE_PLA, + IO_FILE_MOPLA, IO_FILE_SMV, IO_FILE_VERILOG, IO_FILE_UNKNOWN @@ -128,6 +129,7 @@ extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName ); extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ); /*=== abcWritePla.c ===========================================================*/ extern int Io_WritePla( Abc_Ntk_t * pNtk, char * FileName ); +extern int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * FileName ); /*=== abcWriteSmv.c ===========================================================*/ extern int Io_WriteSmv( Abc_Ntk_t * pNtk, char * FileName ); /*=== abcWriteVerilog.c =======================================================*/ diff --git a/src/base/io/ioUtil.c b/src/base/io/ioUtil.c index cc1e9e40..7e7d1701 100644 --- a/src/base/io/ioUtil.c +++ b/src/base/io/ioUtil.c @@ -399,6 +399,10 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType ) if ( !Abc_NtkToSop( pNtkTemp, 1 ) ) return; } + else if ( FileType == IO_FILE_MOPLA ) + { + pNtkTemp = Abc_NtkStrash( pNtk, 0, 0, 0 ); + } else if ( FileType == IO_FILE_BENCH ) { if ( !Abc_NtkIsStrash(pNtk) ) @@ -444,6 +448,8 @@ void Io_Write( Abc_Ntk_t * pNtk, char * pFileName, Io_FileType_t FileType ) Io_WriteBook( pNtkTemp, pFileName ); else if ( FileType == IO_FILE_PLA ) Io_WritePla( pNtkTemp, pFileName ); + else if ( FileType == IO_FILE_MOPLA ) + Io_WriteMoPla( pNtkTemp, pFileName ); else if ( FileType == IO_FILE_EQN ) { if ( !Abc_NtkHasAig(pNtkTemp) ) diff --git a/src/base/io/ioWritePla.c b/src/base/io/ioWritePla.c index ce6ee31f..ea06e113 100644 --- a/src/base/io/ioWritePla.c +++ b/src/base/io/ioWritePla.c @@ -19,6 +19,7 @@ ***********************************************************************/ #include "ioAbc.h" +#include "misc/extra/extraBdd.h" ABC_NAMESPACE_IMPL_START @@ -27,8 +28,6 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -static int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk ); - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -44,43 +43,6 @@ static int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk ); SeeAlso [] ***********************************************************************/ -int Io_WritePla( Abc_Ntk_t * pNtk, char * pFileName ) -{ - Abc_Ntk_t * pExdc; - FILE * pFile; - - assert( Abc_NtkIsSopNetlist(pNtk) ); - assert( Abc_NtkLevel(pNtk) == 1 ); - - pFile = fopen( pFileName, "w" ); - if ( pFile == NULL ) - { - fprintf( stdout, "Io_WritePla(): Cannot open the output file.\n" ); - return 0; - } - fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); - // write the network - Io_WritePlaOne( pFile, pNtk ); - // write EXDC network if it exists - pExdc = Abc_NtkExdc( pNtk ); - if ( pExdc ) - printf( "Io_WritePla: EXDC is not written (warning).\n" ); - // finalize the file - fclose( pFile ); - return 1; -} - -/**Function************************************************************* - - Synopsis [Writes the network in PLA format.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk ) { ProgressBar * pProgress; @@ -192,6 +154,292 @@ int Io_WritePlaOne( FILE * pFile, Abc_Ntk_t * pNtk ) return 1; } +/**Function************************************************************* + + Synopsis [Writes the network in PLA format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_WritePla( Abc_Ntk_t * pNtk, char * pFileName ) +{ + Abc_Ntk_t * pExdc; + FILE * pFile; + + assert( Abc_NtkIsSopNetlist(pNtk) ); + assert( Abc_NtkLevel(pNtk) == 1 ); + + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Io_WritePla(): Cannot open the output file.\n" ); + return 0; + } + fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); + // write the network + Io_WritePlaOne( pFile, pNtk ); + // write EXDC network if it exists + pExdc = Abc_NtkExdc( pNtk ); + if ( pExdc ) + printf( "Io_WritePla: EXDC is not written (warning).\n" ); + // finalize the file + fclose( pFile ); + return 1; +} + + +/**Function************************************************************* + + Synopsis [Writes the network in PLA format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_WriteMoPlaOneInt( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd, Vec_Ptr_t * vFuncs ) +{ + Abc_Obj_t * pNode; + DdNode * bOnset, * bOffset, * bCube, * bFunc, * bTemp, * zCover; + int i, k, nInputs, nOutputs; + int nCubes, fPhase; + + assert( Vec_PtrSize(vFuncs) == Abc_NtkCoNum(pNtk) ); + assert( dd->size == Abc_NtkCiNum(pNtk) ); + assert( dd->size <= 1000 ); + + // collect the parameters + nInputs = Abc_NtkCiNum(pNtk); + nOutputs = Abc_NtkCoNum(pNtk); + assert( nOutputs > 1 ); + + // create extra variables + for ( i = 0; i < nOutputs; i++ ) + Cudd_bddNewVarAtLevel( dd, i ); + assert( dd->size == nInputs + nOutputs ); + + // create ON and OFF sets + bOnset = Cudd_ReadLogicZero( dd ); Cudd_Ref(bOnset); + bOffset = Cudd_ReadLogicZero( dd ); Cudd_Ref(bOffset); + for ( i = 0; i < nOutputs; i++ ) + { + bFunc = (DdNode *)Vec_PtrEntry(vFuncs, i); + // create onset + bCube = Cudd_bddAnd( dd, Cudd_bddIthVar(dd, nInputs+i), bFunc ); Cudd_Ref(bCube); + for ( k = 0; k < nOutputs; k++ ) + if ( k != i ) + { + bCube = Cudd_bddAnd( dd, bTemp = bCube, Cudd_Not(Cudd_bddIthVar(dd, nInputs+k)) ); Cudd_Ref(bCube); + Cudd_RecursiveDeref( dd, bTemp ); + } + bOnset = Cudd_bddOr( dd, bTemp = bOnset, bCube ); Cudd_Ref(bOnset); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bCube ); + // create offset + bCube = Cudd_bddAnd( dd, Cudd_bddIthVar(dd, nInputs+i), Cudd_Not(bFunc) ); Cudd_Ref(bCube); + bOffset = Cudd_bddOr( dd, bTemp = bOffset, bCube ); Cudd_Ref(bOffset); + Cudd_RecursiveDeref( dd, bTemp ); + Cudd_RecursiveDeref( dd, bCube ); + + printf( "Trying %d output.\n", i ); + printf( "Onset = %d nodes.\n", Cudd_DagSize(bOnset) ); + printf( "Offset = %d nodes.\n", Cudd_DagSize(bOffset) ); + } + + Cudd_zddVarsFromBddVars( dd, 2 ); + + // derive ISOP + { + extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover ); + DdNode * bCover, * zCover0, * zCover1; + int nCubes0, nCubes1; + // get the ZDD of the negative polarity + bCover = Cudd_zddIsop( dd, bOffset, Cudd_Not(bOnset), &zCover0 ); + Cudd_Ref( zCover0 ); + Cudd_Ref( bCover ); + Cudd_RecursiveDeref( dd, bCover ); + nCubes0 = Abc_CountZddCubes( dd, zCover0 ); + + // get the ZDD of the positive polarity + bCover = Cudd_zddIsop( dd, bOnset, Cudd_Not(bOffset), &zCover1 ); + Cudd_Ref( zCover1 ); + Cudd_Ref( bCover ); + Cudd_RecursiveDeref( dd, bCover ); + nCubes1 = Abc_CountZddCubes( dd, zCover1 ); + + // compare the number of cubes + if ( nCubes1 <= nCubes0 ) + { // use positive polarity + nCubes = nCubes1; + zCover = zCover1; + Cudd_RecursiveDerefZdd( dd, zCover0 ); + fPhase = 1; + } + else + { // use negative polarity + nCubes = nCubes0; + zCover = zCover0; + Cudd_RecursiveDerefZdd( dd, zCover1 ); + fPhase = 0; + } + } + Cudd_RecursiveDeref( dd, bOnset ); + Cudd_RecursiveDeref( dd, bOffset ); + Cudd_RecursiveDerefZdd( dd, zCover ); + printf( "Cover = %d nodes.\n", Cudd_DagSize(zCover) ); + printf( "ISOP = %d\n", nCubes ); + + // write the header + fprintf( pFile, ".i %d\n", nInputs ); + fprintf( pFile, ".o %d\n", nOutputs ); + fprintf( pFile, ".ilb" ); + Abc_NtkForEachCi( pNtk, pNode, i ) + fprintf( pFile, " %s", Abc_ObjName(pNode) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".ob" ); + Abc_NtkForEachCo( pNtk, pNode, i ) + fprintf( pFile, " %s", Abc_ObjName(pNode) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".p %d\n", nCubes ); + + + fprintf( pFile, ".e\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Writes the network in PLA format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_WriteMoPlaOneIntMinterms( FILE * pFile, Abc_Ntk_t * pNtk, DdManager * dd, Vec_Ptr_t * vFuncs ) +{ + int pValues[1000]; + Abc_Obj_t * pNode; + int i, k, nProducts, nInputs, nOutputs; + assert( Vec_PtrSize(vFuncs) == Abc_NtkCoNum(pNtk) ); + assert( dd->size == Abc_NtkCiNum(pNtk) ); + assert( dd->size <= 1000 ); + + // collect the parameters + nInputs = Abc_NtkCiNum(pNtk); + nOutputs = Abc_NtkCoNum(pNtk); + nProducts = (1 << nInputs); + + // write the header + fprintf( pFile, ".i %d\n", nInputs ); + fprintf( pFile, ".o %d\n", nOutputs ); + fprintf( pFile, ".ilb" ); + Abc_NtkForEachCi( pNtk, pNode, i ) + fprintf( pFile, " %s", Abc_ObjName(pNode) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".ob" ); + Abc_NtkForEachCo( pNtk, pNode, i ) + fprintf( pFile, " %s", Abc_ObjName(pNode) ); + fprintf( pFile, "\n" ); + fprintf( pFile, ".p %d\n", nProducts ); + + // iterate through minterms + for ( k = 0; k < nProducts; k++ ) + { + for ( i = 0; i < nInputs; i++ ) + fprintf( pFile, "%c", '0' + (pValues[i] = ((k >> i) & 1)) ); + fprintf( pFile, " " ); + for ( i = 0; i < nOutputs; i++ ) + fprintf( pFile, "%c", '0' + (Cudd_ReadOne(dd) == Cudd_Eval(dd, (DdNode *)Vec_PtrEntry(vFuncs, i), pValues)) ); + fprintf( pFile, "\n" ); + } + + fprintf( pFile, ".e\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Writes the network in PLA format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_WriteMoPlaOne( FILE * pFile, Abc_Ntk_t * pNtk ) +{ + int fVerbose = 1; + DdManager * dd; + DdNode * bFunc; + Vec_Ptr_t * vFuncsGlob; + Abc_Obj_t * pObj; + int i; + assert( Abc_NtkIsStrash(pNtk) ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, fVerbose ); + if ( dd == NULL ) + return 0; + if ( fVerbose ) + printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); + + // complement the global functions + vFuncsGlob = Vec_PtrAlloc( Abc_NtkCoNum(pNtk) ); + Abc_NtkForEachCo( pNtk, pObj, i ) + Vec_PtrPush( vFuncsGlob, Abc_ObjGlobalBdd(pObj) ); + + // consider minterms + Io_WriteMoPlaOneIntMinterms( pFile, pNtk, dd, vFuncsGlob ); + Abc_NtkFreeGlobalBdds( pNtk, 0 ); + + // cleanup + Vec_PtrForEachEntry( DdNode *, vFuncsGlob, bFunc, i ) + Cudd_RecursiveDeref( dd, bFunc ); + Vec_PtrFree( vFuncsGlob ); + Extra_StopManager( dd ); + return 1; +} + +/**Function************************************************************* + + Synopsis [Writes the network in PLA format.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Io_WriteMoPla( Abc_Ntk_t * pNtk, char * pFileName ) +{ + FILE * pFile; + assert( Abc_NtkIsStrash(pNtk) ); + if ( Abc_NtkCiNum(pNtk) > 16 ) + { + printf( "Cannot write multi-output PLA for more than 16 inputs.\n" ); + return 0; + } + pFile = fopen( pFileName, "w" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Io_WritePla(): Cannot open the output file.\n" ); + return 0; + } + fprintf( pFile, "# Benchmark \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); + Io_WriteMoPlaOne( pFile, pNtk ); + fclose( pFile ); + return 1; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// |