summaryrefslogtreecommitdiffstats
path: root/src/base/io/ioWritePla.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2015-02-03 17:24:30 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2015-02-03 17:24:30 -0800
commiteb270018b92d949953cba3017ae6a540260598c1 (patch)
treebbf58312aefc218f6fe9bc9b9762592a6e4612ca /src/base/io/ioWritePla.c
parentd7d1978e42ca631eacf6a7a49ee75b0184f3ac20 (diff)
downloadabc-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.c326
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 ///