diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2015-02-03 17:24:30 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2015-02-03 17:24:30 -0800 |
commit | eb270018b92d949953cba3017ae6a540260598c1 (patch) | |
tree | bbf58312aefc218f6fe9bc9b9762592a6e4612ca /src/base/io/ioWritePla.c | |
parent | d7d1978e42ca631eacf6a7a49ee75b0184f3ac20 (diff) | |
download | abc-eb270018b92d949953cba3017ae6a540260598c1.tar.gz abc-eb270018b92d949953cba3017ae6a540260598c1.tar.bz2 abc-eb270018b92d949953cba3017ae6a540260598c1.zip |
Esperiments with MO PLA optimization.
Diffstat (limited to 'src/base/io/ioWritePla.c')
-rw-r--r-- | src/base/io/ioWritePla.c | 326 |
1 files changed, 287 insertions, 39 deletions
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 /// |