summaryrefslogtreecommitdiffstats
path: root/src/base/pla/plaSimple.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/pla/plaSimple.c')
-rw-r--r--src/base/pla/plaSimple.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/src/base/pla/plaSimple.c b/src/base/pla/plaSimple.c
new file mode 100644
index 00000000..8fea5c1f
--- /dev/null
+++ b/src/base/pla/plaSimple.c
@@ -0,0 +1,339 @@
+/**CFile****************************************************************
+
+ FileName [plaSimple.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SOP manager.]
+
+ Synopsis [Scalable SOP transformations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - March 18, 2015.]
+
+ Revision [$Id: plaSimple.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "pla.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Dump PLA manager into a BLIF file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Pla_ManDumpPla( Pla_Man_t * p, char * pFileName )
+{
+ // find the number of original variables
+ int nVarsInit = Pla_ManDivNum(p) ? Vec_IntCountZero(&p->vDivs) : Pla_ManInNum(p);
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ else
+ {
+ char * pLits = "-01?";
+ Vec_Str_t * vStr;
+ Vec_Int_t * vCube;
+ int i, k, Lit;
+ // comment
+ fprintf( pFile, "# PLA file written via PLA package in ABC on " );
+ fprintf( pFile, "%s", Extra_TimeStamp() );
+ fprintf( pFile, "\n\n" );
+ // header
+ fprintf( pFile, ".i %d\n", Pla_ManInNum(p) );
+ fprintf( pFile, ".o %d\n", 1 );
+ fprintf( pFile, ".p %d\n", Vec_WecSize(&p->vCubeLits) );
+ // SOP
+ vStr = Vec_StrStart( Pla_ManInNum(p) + 1 );
+ Vec_WecForEachLevel( &p->vCubeLits, vCube, i )
+ {
+ if ( !Vec_IntSize(vCube) )
+ continue;
+ for ( k = 0; k < Pla_ManInNum(p); k++ )
+ Vec_StrWriteEntry( vStr, k, '-' );
+ Vec_IntForEachEntry( vCube, Lit, k )
+ Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (char)(Abc_LitIsCompl(Lit) ? '0' : '1') );
+ fprintf( pFile, "%s 1\n", Vec_StrArray(vStr) );
+ }
+ Vec_StrFree( vStr );
+ fprintf( pFile, ".e\n\n" );
+ fclose( pFile );
+ printf( "Written file \"%s\".\n", pFileName );
+ }
+}
+void Pla_ManDumpBlif( Pla_Man_t * p, char * pFileName )
+{
+ // find the number of original variables
+ int nVarsInit = Pla_ManDivNum(p) ? Vec_IntCountZero(&p->vDivs) : Pla_ManInNum(p);
+ FILE * pFile = fopen( pFileName, "wb" );
+ if ( pFile == NULL )
+ printf( "Cannot open file \"%s\" for writing.\n", pFileName );
+ else
+ {
+ char * pLits = "-01?";
+ Vec_Str_t * vStr;
+ Vec_Int_t * vCube;
+ int i, k, Lit, Div;
+ // comment
+ fprintf( pFile, "# BLIF file written via PLA package in ABC on " );
+ fprintf( pFile, "%s", Extra_TimeStamp() );
+ fprintf( pFile, "\n\n" );
+ // header
+ fprintf( pFile, ".model %s\n", Pla_ManName(p) );
+ fprintf( pFile, ".inputs" );
+ for ( i = 0; i < nVarsInit; i++ )
+ fprintf( pFile, " i%d", i );
+ fprintf( pFile, "\n" );
+ fprintf( pFile, ".outputs o" );
+ fprintf( pFile, "\n" );
+ // SOP
+ fprintf( pFile, ".names" );
+ for ( i = 0; i < Pla_ManInNum(p); i++ )
+ fprintf( pFile, " i%d", i );
+ fprintf( pFile, " o\n" );
+ vStr = Vec_StrStart( Pla_ManInNum(p) + 1 );
+ Vec_WecForEachLevel( &p->vCubeLits, vCube, i )
+ {
+ for ( k = 0; k < Pla_ManInNum(p); k++ )
+ Vec_StrWriteEntry( vStr, k, '-' );
+ Vec_IntForEachEntry( vCube, Lit, k )
+ Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (char)(Abc_LitIsCompl(Lit) ? '0' : '1') );
+ fprintf( pFile, "%s 1\n", Vec_StrArray(vStr) );
+ }
+ Vec_StrFree( vStr );
+ // divisors
+ Vec_IntForEachEntryStart( &p->vDivs, Div, i, nVarsInit )
+ {
+ int pLits[3] = { (Div >> 2) & 0x3FF, (Div >> 12) & 0x3FF, (Div >> 22) & 0x3FF };
+ fprintf( pFile, ".names" );
+ fprintf( pFile, " i%d", Abc_Lit2Var(pLits[0]) );
+ fprintf( pFile, " i%d", Abc_Lit2Var(pLits[1]) );
+ if ( (Div & 3) == 3 ) // MUX
+ fprintf( pFile, " i%d", Abc_Lit2Var(pLits[2]) );
+ fprintf( pFile, " i%d\n", i );
+ if ( (Div & 3) == 1 ) // AND
+ fprintf( pFile, "%d%d 1\n", !Abc_LitIsCompl(pLits[0]), !Abc_LitIsCompl(pLits[1]) );
+ else if ( (Div & 3) == 2 ) // XOR
+ {
+ assert( !Abc_LitIsCompl(pLits[0]) );
+ assert( !Abc_LitIsCompl(pLits[1]) );
+ fprintf( pFile, "10 1\n01 1\n" );
+ }
+ else if ( (Div & 3) == 3 ) // MUX
+ {
+ assert( !Abc_LitIsCompl(pLits[1]) );
+ assert( !Abc_LitIsCompl(pLits[2]) );
+ fprintf( pFile, "%d-0 1\n-11 1\n", !Abc_LitIsCompl(pLits[0]) );
+ }
+ else assert( 0 );
+ }
+ fprintf( pFile, ".end\n\n" );
+ fclose( pFile );
+ printf( "Written file \"%s\".\n", pFileName );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Transforms truth table into an SOP manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Pla_ManExpendDirNum( word * pOn, int nBits, int iMint, int * pVars )
+{
+ int v, nVars = 0;
+ for ( v = 0; v < nBits; v++ )
+ if ( Pla_TtGetBit(pOn, iMint ^ (1 << v)) )
+ pVars[nVars++] = v;
+ return nVars;
+}
+void Pla_PrintBinary( word * pT, int nBits )
+{
+ int v;
+ for ( v = 0; v < nBits; v++ )
+ printf( "%d", Pla_TtGetBit(pT, v) );
+ printf( "\n" );
+}
+Vec_Wrd_t * Pla_ManFxMinimize( word * pOn, int nVars )
+{
+ int i, v, iMint, iVar, nMints = (1 << nVars);
+ int nWords = Abc_Bit6WordNum( nMints );
+ Vec_Wrd_t * vCubes = Vec_WrdAlloc( 1000 );
+ word * pDc = ABC_CALLOC( word, nWords );
+ int Count[32] = {0};
+ int Cubes[32] = {0};
+ Vec_Int_t * vStore = Vec_IntAlloc( 1000 );
+
+ // count the number of expansion directions
+ for ( i = 0; i < nMints; i++ )
+ if ( Pla_TtGetBit(pOn, i) && !Pla_TtGetBit(pDc, i) )
+ {
+ int pDirs[32], nDirs = Pla_ManExpendDirNum(pOn, nVars, i, pDirs);
+ Count[nDirs]++;
+ if ( nDirs == 0 )
+ {
+ Pla_TtSetBit(pDc, i);
+ Cubes[0]++;
+ // save
+ Vec_IntPushTwo( vStore, i, -1 );
+ continue;
+ }
+ if ( nDirs == 1 )
+ {
+ //Pla_PrintBinary( (word *)&i, nVars );
+ //printf( " %d \n", pDirs[0] );
+
+ Pla_TtSetBit(pDc, i);
+ Pla_TtSetBit(pDc, i ^ (1 << pDirs[0]));
+ Cubes[1]++;
+ // save
+ Vec_IntPushTwo( vStore, i, pDirs[0] );
+ continue;
+ }
+ if ( nDirs == 2 && Pla_TtGetBit(pOn, i ^ (1 << pDirs[0]) ^ (1 << pDirs[1])) )
+ {
+ assert( 0 );
+ Pla_TtSetBit(pDc, i);
+ Pla_TtSetBit(pDc, i ^ (1 << pDirs[0]));
+ Pla_TtSetBit(pDc, i ^ (1 << pDirs[1]));
+ Pla_TtSetBit(pDc, i ^ (1 << pDirs[0]) ^ (1 << pDirs[1]));
+ Cubes[2]++;
+ continue;
+ }
+ }
+
+ // go through the remaining cubes
+ for ( i = 0; i < nMints; i++ )
+ if ( Pla_TtGetBit(pOn, i) && !Pla_TtGetBit(pDc, i) )
+ {
+ int pDirs[32], nDirs = Pla_ManExpendDirNum(pOn, nVars, i, pDirs);
+ // find direction, which is not taken
+ for ( v = 0; v < nDirs; v++ )
+ if ( Pla_TtGetBit(pOn, i ^ (1 << pDirs[v])) && !Pla_TtGetBit(pDc, i ^ (1 << pDirs[v])) )
+ break;
+ // if there is no open directions, use any one
+ if ( v == nDirs )
+ v = 0;
+ // mark this one
+ Pla_TtSetBit(pDc, i);
+ Pla_TtSetBit(pDc, i ^ (1 << pDirs[v]));
+ Cubes[10]++;
+ // save
+ Vec_IntPushTwo( vStore, i, pDirs[v] );
+ continue;
+ }
+
+ printf( "\n" );
+ printf( "Truth = %d. ", Pla_TtCountOnes(pOn, nWords) );
+ printf( "Cover = %d. ", Pla_TtCountOnes(pDc, nWords) );
+ printf( "\n" );
+
+ printf( "Count: " );
+ for ( i = 0; i < 16; i++ )
+ if ( Count[i] )
+ printf( "%d=%d ", i, Count[i] );
+ printf( "\n" );
+
+ printf( "Cubes: " );
+ for ( i = 0; i < 16; i++ )
+ if ( Cubes[i] )
+ printf( "%d=%d ", i, Cubes[i] );
+ printf( "\n" );
+
+/*
+ // extract cubes one at a time
+ for ( i = 0; i < nMints; i++ )
+ if ( Pla_TtGetBit(pOn, i) )
+ {
+ word Cube = 0;
+ for ( v = 0; v < nVars; v++ )
+ if ( (i >> v) & 1 )
+ Pla_CubeSetLit( &Cube, v, PLA_LIT_ONE );
+ else
+ Pla_CubeSetLit( &Cube, v, PLA_LIT_ZERO );
+ Vec_WrdPush( vCubes, Cube );
+ }
+*/
+ Vec_IntForEachEntryDouble( vStore, iMint, iVar, i )
+ {
+ word Cube = 0;
+ for ( v = 0; v < nVars; v++ )
+ {
+ if ( v == iVar )
+ continue;
+ if ( (iMint >> v) & 1 )
+ Pla_CubeSetLit( &Cube, v, PLA_LIT_ONE );
+ else
+ Pla_CubeSetLit( &Cube, v, PLA_LIT_ZERO );
+ }
+ Vec_WrdPush( vCubes, Cube );
+ }
+ Vec_IntFree( vStore );
+
+ // collect the minterms
+ ABC_FREE( pDc );
+ return vCubes;
+}
+Pla_Man_t * Pla_ManFxPrepare( int nVars )
+{
+ Pla_Man_t * p; char Buffer[1000];
+ Vec_Bit_t * vFunc = Pla_ManPrimesTable( nVars );
+ Vec_Wrd_t * vSop = Pla_ManFxMinimize( (word *)Vec_BitArray(vFunc), nVars );
+ word Cube, * pCube = &Cube; int i, k, Lit;
+ sprintf( Buffer, "primes%02d", nVars );
+ p = Pla_ManAlloc( Buffer, nVars, 1, Vec_WrdSize(vSop) );
+ Vec_WecInit( &p->vCubeLits, Pla_ManCubeNum(p) );
+ Vec_WecInit( &p->vOccurs, 2*Pla_ManInNum(p) );
+ Vec_WrdForEachEntry( vSop, Cube, i )
+ Pla_CubeForEachLit( nVars, pCube, Lit, k )
+ if ( Lit != PLA_LIT_DASH )
+ {
+ Lit = Abc_Var2Lit( k, Lit == PLA_LIT_ZERO );
+ Vec_WecPush( &p->vCubeLits, i, Lit );
+ Vec_WecPush( &p->vOccurs, Lit, i );
+ }
+ Vec_BitFree( vFunc );
+ Vec_WrdFree( vSop );
+ return p;
+}
+int Pla_ManFxPerformSimple( int nVars )
+{
+ char Buffer[100];
+ Pla_Man_t * p = Pla_ManFxPrepare( nVars );
+ sprintf( Buffer, "primesmin%02d.pla", nVars );
+ Pla_ManDumpPla( p, Buffer );
+ Pla_ManFree( p );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+