diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2015-03-18 19:39:22 +0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2015-03-18 19:39:22 +0700 |
commit | c602cbe33849e9365a3b8e3f13a13e696aa7b9ec (patch) | |
tree | e9b756ac631766e6e7c85dd7e2eb383c087e748c | |
parent | fb5d4a664dc3790e98036a94734a33a848fd3666 (diff) | |
download | abc-c602cbe33849e9365a3b8e3f13a13e696aa7b9ec.tar.gz abc-c602cbe33849e9365a3b8e3f13a13e696aa7b9ec.tar.bz2 abc-c602cbe33849e9365a3b8e3f13a13e696aa7b9ec.zip |
Scalable SOP manipulation package.
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | abclib.dsp | 32 | ||||
-rw-r--r-- | src/base/cba/cbaPrs.h | 9 | ||||
-rw-r--r-- | src/base/main/mainInit.c | 4 | ||||
-rw-r--r-- | src/base/main/mainInt.h | 1 | ||||
-rw-r--r-- | src/base/pla/module.make | 6 | ||||
-rw-r--r-- | src/base/pla/pla.c | 52 | ||||
-rw-r--r-- | src/base/pla/pla.h | 261 | ||||
-rw-r--r-- | src/base/pla/plaCom.c | 485 | ||||
-rw-r--r-- | src/base/pla/plaHash.c | 219 | ||||
-rw-r--r-- | src/base/pla/plaMan.c | 233 | ||||
-rw-r--r-- | src/base/pla/plaMerge.c | 55 | ||||
-rw-r--r-- | src/base/pla/plaRead.c | 224 | ||||
-rw-r--r-- | src/base/pla/plaWrite.c | 112 | ||||
-rw-r--r-- | src/base/wlc/wlcReadSmt.c | 1 | ||||
-rw-r--r-- | src/misc/vec/vecInt.h | 8 |
16 files changed, 1700 insertions, 6 deletions
@@ -13,8 +13,8 @@ PROG := abc MODULES := \ $(wildcard src/ext*) \ - src/base/abc src/base/abci src/base/cmd src/base/io \ - src/base/main src/base/ver src/base/wlc src/base/cba src/base/test \ + src/base/abc src/base/abci src/base/cmd src/base/io src/base/main \ + src/base/ver src/base/wlc src/base/cba src/base/pla src/base/test \ src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse \ src/bdd/reo src/bdd/cas \ src/map/mapper src/map/mio src/map/super src/map/if \ @@ -854,6 +854,38 @@ SOURCE=.\src\base\cba\cbaWriteSmt.c SOURCE=.\src\base\cba\cbaWriteVer.c # End Source File # End Group +# Begin Group "pla" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\base\pla\pla.h +# End Source File +# Begin Source File + +SOURCE=.\src\base\pla\plaCom.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\pla\plaHash.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\pla\plaMan.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\pla\plaMerge.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\pla\plaRead.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\pla\plaWrite.c +# End Source File +# End Group # End Group # Begin Group "bdd" diff --git a/src/base/cba/cbaPrs.h b/src/base/cba/cbaPrs.h index 76f7d060..9c7a1dfe 100644 --- a/src/base/cba/cbaPrs.h +++ b/src/base/cba/cbaPrs.h @@ -241,13 +241,14 @@ static inline char * Prs_ManLoadFile( char * pFileName, char ** ppLimit ) // move the file current reading position to the beginning rewind( pFile ); // load the contents of the file into memory - pBuffer = ABC_ALLOC( char, nFileSize + 3 ); + pBuffer = ABC_ALLOC( char, nFileSize + 16 ); pBuffer[0] = '\n'; RetValue = fread( pBuffer+1, nFileSize, 1, pFile ); + fclose( pFile ); // terminate the string with '\0' - pBuffer[nFileSize + 0] = '\n'; - pBuffer[nFileSize + 1] = '\0'; - *ppLimit = pBuffer + nFileSize + 2; + pBuffer[nFileSize + 1] = '\n'; + pBuffer[nFileSize + 2] = '\0'; + *ppLimit = pBuffer + nFileSize + 3; return pBuffer; } static inline Prs_Man_t * Prs_ManAlloc( char * pFileName ) diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c index eda304aa..b7d3f5f5 100644 --- a/src/base/main/mainInit.c +++ b/src/base/main/mainInit.c @@ -51,6 +51,8 @@ extern void Wlc_Init( Abc_Frame_t * pAbc ); extern void Wlc_End( Abc_Frame_t * pAbc ); extern void Cba_Init( Abc_Frame_t * pAbc ); extern void Cba_End( Abc_Frame_t * pAbc ); +extern void Pla_Init( Abc_Frame_t * pAbc ); +extern void Pla_End( Abc_Frame_t * pAbc ); extern void Test_Init( Abc_Frame_t * pAbc ); extern void Test_End( Abc_Frame_t * pAbc ); extern void Abc2_Init( Abc_Frame_t * pAbc ); @@ -107,6 +109,7 @@ void Abc_FrameInit( Abc_Frame_t * pAbc ) Scl_Init( pAbc ); Wlc_Init( pAbc ); Cba_Init( pAbc ); + Pla_Init( pAbc ); Test_Init( pAbc ); for( p = s_InitializerStart ; p ; p = p->next ) if(p->init) @@ -143,6 +146,7 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc ) Scl_End( pAbc ); Wlc_End( pAbc ); Cba_End( pAbc ); + Pla_End( pAbc ); Test_End( pAbc ); } diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index 89b961d4..6a6e458a 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -128,6 +128,7 @@ struct Abc_Frame_t_ void * pAbc85Delay; void * pAbcWlc; void * pAbcCba; + void * pAbcPla; }; typedef void (*Abc_Frame_Initialization_Func)( Abc_Frame_t * pAbc ); diff --git a/src/base/pla/module.make b/src/base/pla/module.make new file mode 100644 index 00000000..ab883fef --- /dev/null +++ b/src/base/pla/module.make @@ -0,0 +1,6 @@ +SRC += src/base/pla/plaCom.c \ + src/base/pla/plaHash.c \ + src/base/pla/plaMan.c \ + src/base/pla/plaMerge.c \ + src/base/pla/plaRead.c \ + src/base/pla/plaWrite.c diff --git a/src/base/pla/pla.c b/src/base/pla/pla.c new file mode 100644 index 00000000..6219bd34 --- /dev/null +++ b/src/base/pla/pla.c @@ -0,0 +1,52 @@ +/**CFile**************************************************************** + + FileName [pla.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: pla.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pla.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/pla/pla.h b/src/base/pla/pla.h new file mode 100644 index 00000000..b9816179 --- /dev/null +++ b/src/base/pla/pla.h @@ -0,0 +1,261 @@ +/**CFile**************************************************************** + + FileName [pla.h] + + 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: pla.h,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__base__wlc__wlc_h +#define ABC__base__wlc__wlc_h + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "aig/gia/gia.h" +#include "misc/extra/extra.h" +#include "base/main/mainInt.h" +//#include "misc/util/utilTruth.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +ABC_NAMESPACE_HEADER_START + +#define MASK55 ABC_CONST(0x5555555555555555) + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +// file types +typedef enum { + PLA_FILE_FD = 0, + PLA_FILE_F, + PLA_FILE_FR, + PLA_FILE_FDR, + PLA_FILE_NONE +} Pla_File_t; + +// literal types +typedef enum { + PLA_LIT_DASH = 0, + PLA_LIT_ZERO, + PLA_LIT_ONE, + PLA_LIT_FULL +} Pla_Lit_t; + + +typedef struct Pla_Man_t_ Pla_Man_t; +struct Pla_Man_t_ +{ + char * pName; // model name + char * pSpec; // input file + Pla_File_t Type; // file type + int nIns; // inputs + int nOuts; // outputs + int nInWords; // words of input data + int nOutWords; // words of output data + Vec_Int_t vCubes; // cubes + Vec_Int_t vHashes; // hash values + Vec_Wrd_t vInBits; // input bits + Vec_Wrd_t vOutBits; // output bits + Vec_Wec_t vLits; // cubes as interger arrays + Vec_Wec_t vOccurs; // occurent counters for the literals +}; + +static inline int Pla_ManInNum( Pla_Man_t * p ) { return p->nIns; } +static inline int Pla_ManOutNum( Pla_Man_t * p ) { return p->nOuts; } +static inline int Pla_ManCubeNum( Pla_Man_t * p ) { return Vec_IntSize( &p->vCubes ); } + +static inline word * Pla_CubeIn( Pla_Man_t * p, int i ) { return Vec_WrdEntryP(&p->vInBits, i * p->nInWords); } +static inline word * Pla_CubeOut( Pla_Man_t * p, int i ) { return Vec_WrdEntryP(&p->vOutBits, i * p->nOutWords); } + +static inline int Pla_CubeGetLit( word * p, int k ) { return (int)(p[k>>5] >> ((k<<1) & 63)) & 3; } +static inline void Pla_CubeSetLit( word * p, int k, Pla_Lit_t d ) { p[k>>5] |= (((word)d)<<((k<<1) & 63)); } +static inline void Pla_CubeXorLit( word * p, int k, Pla_Lit_t d ) { p[k>>5] ^= (((word)d)<<((k<<1) & 63)); } + + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// ITERATORS /// +//////////////////////////////////////////////////////////////////////// + +#define Pla_ForEachCubeIn( p, pCube, i ) \ + for ( i = 0; (i < Pla_ManCubeNum(p)) && (((pCube) = Pla_CubeIn(p, i)), 1); i++ ) +#define Pla_ForEachCubeInStart( p, pCube, i, Start ) \ + for ( i = Start; (i < Pla_ManCubeNum(p)) && (((pCube) = Pla_CubeIn(p, i)), 1); i++ ) + +#define Pla_ForEachCubeOut( p, pCube, i ) \ + for ( i = 0; (i < Pla_ManCubeNum(p)) && (((pCube) = Pla_CubeOut(p, i)), 1); i++ ) +#define Pla_ForEachCubeInOut( p, pCubeIn, pCubeOut, i ) \ + for ( i = 0; (i < Pla_ManCubeNum(p)) && (((pCubeIn) = Pla_CubeIn(p, i)), 1) && (((pCubeOut) = Pla_CubeOut(p, i)), 1); i++ ) + +#define Pla_CubeForEachLit( nVars, pCube, Lit, i ) \ + for ( i = 0; (i < nVars) && (((Lit) = Pla_CubeGetLit(pCube, i)), 1); i++ ) +#define Pla_CubeForEachLitIn( p, pCube, Lit, i ) \ + Pla_CubeForEachLit( Pla_ManInNum(p), pCube, Lit, i ) +#define Pla_CubeForEachLitOut( p, pCube, Lit, i ) \ + Pla_CubeForEachLit( Pla_ManOutNum(p), pCube, Lit, i ) + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Checks if cubes are distance-1.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Pla_OnlyOneOne( word t ) +{ + return t ? ((t & (t-1)) == 0) : 0; +} +static inline int Pla_CubesAreDistance1( word * p, word * q, int nWords ) +{ + word Test; int c, fFound = 0; + for ( c = 0; c < nWords; c++ ) + { + if ( p[c] == q[c] ) + continue; + if ( fFound ) + return 0; + // check if the number of 1s is one, which means exactly one different literal (0/1, -/1, -/0) + Test = ((p[c] ^ q[c]) | ((p[c] ^ q[c]) >> 1)) & MASK55; + if ( !Pla_OnlyOneOne(Test) ) + return 0; + fFound = 1; + } + return fFound; +} +static inline int Pla_CubesAreConsensus( word * p, word * q, int nWords, int * piVar ) +{ + word Test; int c, fFound = 0; + for ( c = 0; c < nWords; c++ ) + { + if ( p[c] == q[c] ) + continue; + if ( fFound ) + return 0; + // check if the number of 1s is one, which means exactly one opposite literal (0/1) but may have other diffs (-/0 or -/1) + Test = ((p[c] ^ q[c]) & ((p[c] ^ q[c]) >> 1)) & MASK55; + if ( !Pla_OnlyOneOne(Test) ) + return 0; + fFound = 1; + if ( piVar ) *piVar = c * 32 + Abc_Tt6FirstBit(Test)/2; + } + return fFound; +} + +/**Function************************************************************* + + Synopsis [Manager APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Pla_Man_t * Pla_ManAlloc( char * pFileName, int nIns, int nOuts, int nCubes ) +{ + Pla_Man_t * p = ABC_CALLOC( Pla_Man_t, 1 ); + p->pName = Extra_FileDesignName( pFileName ); + p->pSpec = Abc_UtilStrsav( pFileName ); + p->nIns = nIns; + p->nOuts = nOuts; + p->nInWords = Abc_Bit6WordNum( 2*nIns ); + p->nOutWords = Abc_Bit6WordNum( 2*nOuts ); + Vec_IntFillNatural( &p->vCubes, nCubes ); + Vec_WrdFill( &p->vInBits, Pla_ManCubeNum(p) * p->nInWords, 0 ); + Vec_WrdFill( &p->vOutBits, Pla_ManCubeNum(p) * p->nOutWords, 0 ); + return p; +} +static inline void Pla_ManFree( Pla_Man_t * p ) +{ + Vec_IntErase( &p->vCubes ); + Vec_IntErase( &p->vHashes ); + Vec_WrdErase( &p->vInBits ); + Vec_WrdErase( &p->vOutBits ); + Vec_WecErase( &p->vLits ); + Vec_WecErase( &p->vOccurs ); + ABC_FREE( p->pName ); + ABC_FREE( p->pSpec ); + ABC_FREE( p ); +} +static inline int Pla_ManLitInNum( Pla_Man_t * p ) +{ + word * pCube; int i, k, Lit, Count = 0; + Pla_ForEachCubeIn( p, pCube, i ) + Pla_CubeForEachLitIn( p, pCube, Lit, k ) + Count += Lit != PLA_LIT_DASH; + return Count; +} +static inline int Pla_ManLitOutNum( Pla_Man_t * p ) +{ + word * pCube; int i, k, Lit, Count = 0; + Pla_ForEachCubeOut( p, pCube, i ) + Pla_CubeForEachLitOut( p, pCube, Lit, k ) + Count += Lit == PLA_LIT_ONE; + return Count; +} +static inline void Pla_ManPrintStats( Pla_Man_t * p, int fVerbose ) +{ + printf( "%-16s : ", p->pName ); + printf( "In =%4d ", Pla_ManInNum(p) ); + printf( "Out =%4d ", Pla_ManOutNum(p) ); + printf( "Cube =%8d ", Pla_ManCubeNum(p) ); + printf( "LitIn =%8d ", Pla_ManLitInNum(p) ); + printf( "LitOut =%8d ", Pla_ManLitOutNum(p) ); + printf( "%\n" ); +} + + +/*=== plaHash.c ========================================================*/ +extern int Pla_ManHashDist1NumTest( Pla_Man_t * p ); +/*=== plaMan.c ========================================================*/ +extern Pla_Man_t * Pla_ManPrimeDetector( int nVars ); +extern Pla_Man_t * Pla_ManGenerate( int nIns, int nOuts, int nCubes, int fVerbose ); +extern void Pla_ManConvertFromBits( Pla_Man_t * p ); +extern void Pla_ManConvertToBits( Pla_Man_t * p ); +extern int Pla_ManDist1NumTest( Pla_Man_t * p ); +/*=== plaMerge.c ========================================================*/ +extern int Pla_ManDist1Merge( Pla_Man_t * p ); +/*=== plaRead.c ========================================================*/ +extern Pla_Man_t * Pla_ReadPla( char * pFileName ); +/*=== plaWrite.c ========================================================*/ +extern void Pla_WritePla( Pla_Man_t * p, char * pFileName ); + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/base/pla/plaCom.c b/src/base/pla/plaCom.c new file mode 100644 index 00000000..5ccfe98b --- /dev/null +++ b/src/base/pla/plaCom.c @@ -0,0 +1,485 @@ +/**CFile**************************************************************** + + FileName [plaCom.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: plaCom.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pla.h" +#include "base/main/mainInt.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Abc_CommandReadPla ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandWritePla ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandMerge ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static inline Pla_Man_t * Pla_AbcGetMan( Abc_Frame_t * pAbc ) { return (Pla_Man_t *)pAbc->pAbcPla; } +static inline void Pla_AbcFreeMan( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcPla ) Pla_ManFree(Pla_AbcGetMan(pAbc)); } +static inline void Pla_AbcUpdateMan( Abc_Frame_t * pAbc, Pla_Man_t * p ) { Pla_AbcFreeMan(pAbc); pAbc->pAbcPla = p; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Pla_Init( Abc_Frame_t * pAbc ) +{ + Cmd_CommandAdd( pAbc, "Two-level", "|read", Abc_CommandReadPla, 0 ); + Cmd_CommandAdd( pAbc, "Two-level", "|write", Abc_CommandWritePla, 0 ); + Cmd_CommandAdd( pAbc, "Two-level", "|ps", Abc_CommandPs, 0 ); + Cmd_CommandAdd( pAbc, "Two-level", "|gen", Abc_CommandGen, 0 ); + Cmd_CommandAdd( pAbc, "Two-level", "|merge", Abc_CommandMerge, 0 ); + Cmd_CommandAdd( pAbc, "Two-level", "|test", Abc_CommandTest, 0 ); +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Pla_End( Abc_Frame_t * pAbc ) +{ + Pla_AbcFreeMan( pAbc ); +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Pla_SetMan( Abc_Frame_t * pAbc, Pla_Man_t * p ) +{ + Pla_AbcUpdateMan( pAbc, p ); +} + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandReadPla( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + FILE * pFile; + Pla_Man_t * p = NULL; + char * pFileName = NULL; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + printf( "Abc_CommandReadPla(): Input file name should be given on the command line.\n" ); + return 0; + } + // get the file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = fopen( pFileName, "r" )) == NULL ) + { + Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); + if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".pla", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); + Abc_Print( 1, "\n" ); + return 0; + } + fclose( pFile ); + + // perform reading + if ( !strcmp( Extra_FileNameExtension(pFileName), "pla" ) ) + p = Pla_ReadPla( pFileName ); + else + { + printf( "Abc_CommandReadPla(): Unknown file extension.\n" ); + return 0; + } + Pla_AbcUpdateMan( pAbc, p ); + return 0; +usage: + Abc_Print( -2, "usage: |read [-vh] <file_name>\n" ); + Abc_Print( -2, "\t reads the SOP from a PLA file\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandWritePla( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Pla_Man_t * p = Pla_AbcGetMan(pAbc); + char * pFileName = NULL; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Abc_CommandWritePla(): There is no current design.\n" ); + return 0; + } + if ( argc == globalUtilOptind ) + pFileName = Extra_FileNameGenericAppend( p->pName, "_out.v" ); + else if ( argc == globalUtilOptind + 1 ) + pFileName = argv[globalUtilOptind]; + else + { + printf( "Output file name should be given on the command line.\n" ); + return 0; + } + Pla_WritePla( p, pFileName ); + return 0; +usage: + Abc_Print( -2, "usage: |write [-vh]\n" ); + Abc_Print( -2, "\t writes the SOP into a PLA file\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Pla_Man_t * p = Pla_AbcGetMan(pAbc); + int fShowMulti = 0; + int fShowAdder = 0; + int fDistrib = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "madvh" ) ) != EOF ) + { + switch ( c ) + { + case 'm': + fShowMulti ^= 1; + break; + case 'a': + fShowAdder ^= 1; + break; + case 'd': + fDistrib ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Abc_CommandPs(): There is no current design.\n" ); + return 0; + } + Pla_ManPrintStats( p, fVerbose ); + return 0; +usage: + Abc_Print( -2, "usage: |ps [-madvh]\n" ); + Abc_Print( -2, "\t prints statistics\n" ); + Abc_Print( -2, "\t-m : toggle printing multipliers [default = %s]\n", fShowMulti? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle printing adders [default = %s]\n", fShowAdder? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle printing distrubition [default = %s]\n", fDistrib? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandGen( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Pla_Man_t * p = NULL; + int nInputs = 8; + int nOutputs = 1; + int nCubes = 20; + int Seed = 0; + int fPrimes = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "IOPSpvh" ) ) != EOF ) + { + switch ( c ) + { + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + nInputs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nInputs < 0 ) + goto usage; + break; + case 'O': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-O\" should be followed by an integer.\n" ); + goto usage; + } + nOutputs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nOutputs < 0 ) + goto usage; + break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" ); + goto usage; + } + nCubes = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCubes < 0 ) + goto usage; + break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + Seed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Seed < 0 ) + goto usage; + break; + case 'p': + fPrimes ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( fPrimes ) + p = Pla_ManPrimeDetector( nInputs ); + else + { + Gia_ManRandom( 1 ); + for ( c = 0; c < Seed; c++ ) + Gia_ManRandom( 0 ); + p = Pla_ManGenerate( nInputs, nOutputs, nCubes, fVerbose ); + } + Pla_AbcUpdateMan( pAbc, p ); + return 0; +usage: + Abc_Print( -2, "usage: |gen [-IOPS num] [-pvh]\n" ); + Abc_Print( -2, "\t generate random or specialized SOP\n" ); + Abc_Print( -2, "\t-I num : the number of inputs [default = %d]\n", nInputs ); + Abc_Print( -2, "\t-O num : the number of outputs [default = %d]\n", nOutputs ); + Abc_Print( -2, "\t-P num : the number of products [default = %d]\n", nCubes ); + Abc_Print( -2, "\t-S num : ramdom seed (0 <= num <= 1000) [default = %d]\n", Seed ); + Abc_Print( -2, "\t-p : toggle generating prime detector [default = %s]\n", fPrimes? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandMerge( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Pla_Man_t * p = Pla_AbcGetMan(pAbc); + int c, fMulti = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "mvh" ) ) != EOF ) + { + switch ( c ) + { + case 'm': + fMulti ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Abc_CommandMerge(): There is no current design.\n" ); + return 0; + } + // transform + Pla_ManDist1Merge( p ); + return 0; +usage: + Abc_Print( -2, "usage: |merge [-mvh]\n" ); + Abc_Print( -2, "\t performs distance-1 merge using cube hashing\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Pla_Man_t * p = Pla_AbcGetMan(pAbc); + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( p == NULL ) + { + Abc_Print( 1, "Abc_CommandTest(): There is no current design.\n" ); + return 0; + } + Pla_ManHashDist1NumTest( p ); + //Pla_ManConvertFromBits( p ); + //Pla_ManConvertToBits( p ); + return 0; +usage: + Abc_Print( -2, "usage: |test [-vh]\n" ); + Abc_Print( -2, "\t experiments with SOPs\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/pla/plaHash.c b/src/base/pla/plaHash.c new file mode 100644 index 00000000..d05bd9c9 --- /dev/null +++ b/src/base/pla/plaHash.c @@ -0,0 +1,219 @@ +/**CFile**************************************************************** + + FileName [plaHash.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: plaHash.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pla.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define PLA_HASH_VALUE_NUM 256 +static unsigned s_PlaHashValues[PLA_HASH_VALUE_NUM] = +{ + 0x984b6ad9,0x18a6eed3,0x950353e2,0x6222f6eb,0xdfbedd47,0xef0f9023,0xac932a26,0x590eaf55, + 0x97d0a034,0xdc36cd2e,0x22736b37,0xdc9066b0,0x2eb2f98b,0x5d9c7baf,0x85747c9e,0x8aca1055, + 0x50d66b74,0x2f01ae9e,0xa1a80123,0x3e1ce2dc,0xebedbc57,0x4e68bc34,0x855ee0cf,0x17275120, + 0x2ae7f2df,0xf71039eb,0x7c283eec,0x70cd1137,0x7cf651f3,0xa87bfa7a,0x14d87f02,0xe82e197d, + 0x8d8a5ebe,0x1e6a15dc,0x197d49db,0x5bab9c89,0x4b55dea7,0x55dede49,0x9a6a8080,0xe5e51035, + 0xe148d658,0x8a17eb3b,0xe22e4b38,0xe5be2a9a,0xbe938cbb,0x3b981069,0x7f9c0c8e,0xf756df10, + 0x8fa783f7,0x252062ce,0x3dc46b4b,0xf70f6432,0x3f378276,0x44b137a1,0x2bf74b77,0x04892ed6, + 0xfd318de1,0xd58c235e,0x94c6d25b,0x7aa5f218,0x35c9e921,0x5732fbbb,0x06026481,0xf584a44f, + 0x946e1b5f,0x8463d5b2,0x4ebca7b2,0x54887b15,0x08d1e804,0x5b22067d,0x794580f6,0xb351ea43, + 0xbce555b9,0x19ae2194,0xd32f1396,0x6fc1a7f1,0x1fd8a867,0x3a89fdb0,0xea49c61c,0x25f8a879, + 0xde1e6437,0x7c74afca,0x8ba63e50,0xb1572074,0xe4655092,0xdb6f8b1c,0xc2955f3c,0x327f85ba, + 0x60a17021,0x95bd261d,0xdea94f28,0x04528b65,0xbe0109cc,0x26dd5688,0x6ab2729d,0xc4f029ce, + 0xacf7a0be,0x4c912f55,0x34c06e65,0x4fbb938e,0x1533fb5f,0x03da06bd,0x48262889,0xc2523d7d, + 0x28a71d57,0x89f9713a,0xf574c551,0x7a99deb5,0x52834d91,0x5a6f4484,0xc67ba946,0x13ae698f, + 0x3e390f34,0x34fc9593,0x894c7932,0x6cf414a3,0xdb7928ab,0x13a3b8a3,0x4b381c1d,0xa10b54cb, + 0x55359d9d,0x35a3422a,0x58d1b551,0x0fd4de20,0x199eb3f4,0x167e09e2,0x3ee6a956,0x5371a7fa, + 0xd424efda,0x74f521c5,0xcb899ff6,0x4a42e4f4,0x747917b6,0x4b08df0b,0x090c7a39,0x11e909e4, + 0x258e2e32,0xd9fad92d,0x48fe5f69,0x0545cde6,0x55937b37,0x9b4ae4e4,0x1332b40e,0xc3792351, + 0xaff982ef,0x4dba132a,0x38b81ef1,0x28e641bf,0x227208c1,0xec4bbe37,0xc4e1821c,0x512c9d09, + 0xdaef1257,0xb63e7784,0x043e04d7,0x9c2cea47,0x45a0e59a,0x281315ca,0x849f0aac,0xa4071ed3, + 0x0ef707b3,0xfe8dac02,0x12173864,0x471f6d46,0x24a53c0a,0x35ab9265,0xbbf77406,0xa2144e79, + 0xb39a884a,0x0baf5b6d,0xcccee3dd,0x12c77584,0x2907325b,0xfd1adcd2,0xd16ee972,0x345ad6c1, + 0x315ebe66,0xc7ad2b8d,0x99e82c8d,0xe52da8c8,0xba50f1d3,0x66689cd8,0x2e8e9138,0x43e15e74, + 0xf1ced14d,0x188ec52a,0xe0ef3cbb,0xa958aedc,0x4107a1bc,0x5a9e7a3e,0x3bde939f,0xb5b28d5a, + 0x596fe848,0xe85ad00c,0x0b6b3aae,0x44503086,0x25b5695c,0xc0c31dcd,0x5ee617f0,0x74d40c3a, + 0xd2cb2b9f,0x1e19f5fa,0x81e24faf,0xa01ed68f,0xcee172fc,0x7fdf2e4d,0x002f4774,0x664f82dd, + 0xc569c39a,0xa2d4dcbe,0xaadea306,0xa4c947bf,0xa413e4e3,0x81fb5486,0x8a404970,0x752c980c, + 0x98d1d881,0x5c932c1e,0xeee65dfb,0x37592cdd,0x0fd4e65b,0xad1d383f,0x62a1452f,0x8872f68d, + 0xb58c919b,0x345c8ee3,0xb583a6d6,0x43d72cb3,0x77aaa0aa,0xeb508242,0xf2db64f8,0x86294328, + 0x82211731,0x1239a9d5,0x673ba5de,0xaf4af007,0x44203b19,0x2399d955,0xa175cd12,0x595928a7, + 0x6918928b,0xde3126bb,0x6c99835c,0x63ba1fa2,0xdebbdff0,0x3d02e541,0xd6f7aac6,0xe80b4cd0, + 0xd0fa29f1,0x804cac5e,0x2c226798,0x462f624c,0xad05b377,0x22924fcd,0xfbea205c,0x1b47586d +}; + +static inline int Pla_HashValue( int i ) { assert( i >= 0 && i < PLA_HASH_VALUE_NUM ); return s_PlaHashValues[i] & 0xFFFFFF; } + + +#define PLA_LIT_UNUSED 0xFFFF + +typedef struct Tab_Obj_t_ Tab_Obj_t; +struct Tab_Obj_t_ +{ + int Table; + int Next; + int Cube; + unsigned VarA : 16; + unsigned VarB : 16; +}; +typedef struct Tab_Man_t_ Tab_Man_t; +struct Tab_Man_t_ +{ + int SizeMask; // table size (2^Degree-1) + int nBins; // number of entries + Tab_Obj_t * pBins; // hash table (lits -> cube + lit + lit) + Pla_Man_t * pMan; // manager +}; + +static inline Tab_Obj_t * Tab_ManBin( Tab_Man_t * p, int Value ) { return p->pBins + (Value & p->SizeMask); } +static inline Tab_Obj_t * Tab_ManEntry( Tab_Man_t * p, int i ) { return i ? p->pBins + i : NULL; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Tab_Man_t * Tab_ManAlloc( int LogSize, Pla_Man_t * pMan ) +{ + Tab_Man_t * p = ABC_CALLOC( Tab_Man_t, 1 ); + assert( LogSize >= 4 && LogSize <= 24 ); + p->SizeMask = (1 << LogSize) - 1; + p->pBins = ABC_CALLOC( Tab_Obj_t, p->SizeMask + 1 ); + p->nBins = 1; + p->pMan = pMan; + return p; +} +static inline void Tab_ManFree( Tab_Man_t * p ) +{ + ABC_FREE( p->pBins ); + ABC_FREE( p ); +} +static inline void Tab_ManHashInsert( Tab_Man_t * p, int Value, int iCube ) +{ + Tab_Obj_t * pBin = Tab_ManBin( p, Value ); + Tab_Obj_t * pCell = p->pBins + p->nBins; + pCell->Cube = iCube; + pCell->Next = pBin->Table; + pBin->Table = p->nBins++; +} +static inline int Tab_ManHashLookup( Tab_Man_t * p, int Value, Vec_Int_t * vCube ) +{ + Tab_Obj_t * pEnt, * pBin = Tab_ManBin( p, Value ); + for ( pEnt = Tab_ManEntry(p, pBin->Table); pEnt; pEnt = Tab_ManEntry(p, pEnt->Next) ) + if ( Vec_IntEqual( Vec_WecEntry(&p->pMan->vLits, pEnt->Cube), vCube ) ) + return 1; + return 0; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Pla_CubeHashValue( Vec_Int_t * vCube ) +{ + int i, Lit, Value = 0; + Vec_IntForEachEntry( vCube, Lit, i ) + Value += Pla_HashValue(Lit); + return Value; +} +void Pla_ManHashCubes( Pla_Man_t * p, Tab_Man_t * pTab ) +{ + Vec_Int_t * vCube; int i, Value; + Vec_IntClear( &p->vHashes ); + Vec_IntGrow( &p->vHashes, Pla_ManCubeNum(p) ); + Vec_WecForEachLevel( &p->vLits, vCube, i ) + { + Value = Pla_CubeHashValue(vCube); + Vec_IntPush( &p->vHashes, Value ); + Tab_ManHashInsert( pTab, Value, i ); + } +} +int Pla_ManHashDistance1( Pla_Man_t * p ) +{ + Tab_Man_t * pTab; + Vec_Int_t * vCube; + Vec_Int_t * vCubeCopy = Vec_IntAlloc( p->nIns ); + int nBits = Abc_Base2Log( Pla_ManCubeNum(p) ) + 2; + int i, k, Lit, Value, ValueCopy, Count = 0; + assert( nBits <= 24 ); + pTab = Tab_ManAlloc( nBits, p ); + Pla_ManConvertFromBits( p ); + Pla_ManHashCubes( p, pTab ); + Vec_WecForEachLevel( &p->vLits, vCube, i ) + { + Vec_IntClear( vCubeCopy ); + Vec_IntAppend( vCubeCopy, vCube ); + Value = ValueCopy = Vec_IntEntry( &p->vHashes, i ); + Vec_IntForEachEntry( vCubeCopy, Lit, k ) + { + // create new + Value += Pla_HashValue(Abc_LitNot(Lit)) - Pla_HashValue(Lit); + Vec_IntWriteEntry( vCubeCopy, k, Abc_LitNot(Lit) ); + // check the cube + Count += Tab_ManHashLookup( pTab, Value, vCubeCopy ); + // create old + Value -= Pla_HashValue(Abc_LitNot(Lit)) - Pla_HashValue(Lit); + Vec_IntWriteEntry( vCubeCopy, k, Lit ); + } + assert( Value == ValueCopy ); + } + Vec_IntFree( vCubeCopy ); + Tab_ManFree( pTab ); + assert( !(Count & 1) ); + return Count/2; +} +int Pla_ManHashDist1NumTest( Pla_Man_t * p ) +{ + abctime clk = Abc_Clock(); + int Count = Pla_ManHashDistance1( p ); + printf( "Found %d pairs among %d cubes using cube hashing. ", Count, Pla_ManCubeNum(p) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/pla/plaMan.c b/src/base/pla/plaMan.c new file mode 100644 index 00000000..bc3cd8ad --- /dev/null +++ b/src/base/pla/plaMan.c @@ -0,0 +1,233 @@ +/**CFile**************************************************************** + + FileName [plaMan.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: plaMan.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pla.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Generates prime detector for the given bit-widths.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Pla_GenPrimes( int nVars ) +{ + int i, n, nBits = ( 1 << nVars ); + Vec_Bit_t * vMap = Vec_BitStart( nBits ); + Vec_Int_t * vPrimes = Vec_IntAlloc( 1000 ); + Vec_BitWriteEntry(vMap, 0, 1); + Vec_BitWriteEntry(vMap, 1, 1); + for ( n = 2; n < nBits; n++ ) + if ( !Vec_BitEntry(vMap, n) ) + for ( i = 2*n; i < nBits; i += n ) + Vec_BitWriteEntry(vMap, i, 1); + for ( n = 2; n < nBits; n++ ) + if ( !Vec_BitEntry(vMap, n) ) + Vec_IntPush( vPrimes, n ); + printf( "Primes up to 2^%d = %d\n", nVars, Vec_IntSize(vPrimes) ); +// Abc_GenCountHits1( vMap, vPrimes, nVars ); + Vec_BitFree( vMap ); + return vPrimes; +} +Pla_Man_t * Pla_GenFromMinterms( char * pName, Vec_Int_t * vMints, int nVars ) +{ + Pla_Man_t * p = Pla_ManAlloc( pName, nVars, 1, Vec_IntSize(vMints) ); + int i, k, Lit, Mint; + word * pCube; + Pla_ForEachCubeIn( p, pCube, i ) + { + Mint = Vec_IntEntry(vMints, i); + Pla_CubeForEachLitIn( p, pCube, Lit, k ) + Pla_CubeSetLit( pCube, k, ((Mint >> k) & 1) ? PLA_LIT_ONE : PLA_LIT_ZERO ); + } + Pla_ForEachCubeOut( p, pCube, i ) + Pla_CubeSetLit( pCube, 0, PLA_LIT_ONE ); + return p; +} +Pla_Man_t * Pla_ManPrimeDetector( int nVars ) +{ + char pName[1000]; + Pla_Man_t * p; + Vec_Int_t * vMints = Pla_GenPrimes( nVars ); + sprintf( pName, "primes%02d", nVars ); + p = Pla_GenFromMinterms( pName, vMints, nVars ); + Vec_IntFree( vMints ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Bit_t * Pla_GenRandom( int nVars, int nNums, int fNonZero ) +{ + int Mint, Count = 0; + Vec_Bit_t * vBits = Vec_BitStart( 1 << nVars ); + assert( nVars > 0 && nVars <= 30 ); + assert( nNums > 0 && nNums < (1 << (nVars - 1)) ); + while ( Count < nNums ) + { + Mint = Gia_ManRandom(0) & ((1 << nVars) - 1); + if ( fNonZero && Mint == 0 ) + continue; + if ( Vec_BitEntry(vBits, Mint) ) + continue; + Vec_BitWriteEntry( vBits, Mint, 1 ); + Count++; + } + return vBits; +} +Pla_Man_t * Pla_ManGenerate( int nInputs, int nOutputs, int nCubes, int fVerbose ) +{ + Vec_Bit_t * vBits; + int i, k, Count; + word * pCube; + Pla_Man_t * p = Pla_ManAlloc( "rand", nInputs, nOutputs, nCubes ); + // generate nCube random input minterms + vBits = Pla_GenRandom( nInputs, nCubes, 0 ); + for ( i = Count = 0; i < Vec_BitSize(vBits); i++ ) + if ( Vec_BitEntry(vBits, i) ) + { + pCube = Pla_CubeIn( p, Count++ ); + for ( k = 0; k < nInputs; k++ ) + Pla_CubeSetLit( pCube, k, ((i >> k) & 1) ? PLA_LIT_ONE : PLA_LIT_ZERO ); + } + assert( Count == nCubes ); + Vec_BitFree( vBits ); + // generate nCube random output minterms + if ( nOutputs > 1 ) + { + vBits = Pla_GenRandom( nOutputs, nCubes, 1 ); + for ( i = Count = 0; i < Vec_BitSize(vBits); i++ ) + if ( Vec_BitEntry(vBits, i) ) + { + pCube = Pla_CubeOut( p, Count++ ); + for ( k = 0; k < nOutputs; k++ ) + Pla_CubeSetLit( pCube, k, ((i >> k) & 1) ? PLA_LIT_ONE : PLA_LIT_ZERO ); + } + assert( Count == nCubes ); + Vec_BitFree( vBits ); + } + else + { + Pla_ForEachCubeOut( p, pCube, i ) + Pla_CubeSetLit( pCube, 0, PLA_LIT_ONE ); + } + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ManConvertFromBits( Pla_Man_t * p ) +{ + word * pCube; int i, k, Lit; + Vec_WecClear( &p->vLits ); + Vec_WecClear( &p->vOccurs ); + Vec_WecInit( &p->vLits, Pla_ManCubeNum(p) ); + Vec_WecInit( &p->vOccurs, 2*Pla_ManInNum(p) ); + Pla_ForEachCubeIn( p, pCube, i ) + Pla_CubeForEachLitIn( p, pCube, Lit, k ) + if ( Lit != PLA_LIT_DASH ) + { + Lit = Abc_Var2Lit( k, Lit == PLA_LIT_ZERO ); + Vec_WecPush( &p->vLits, i, Lit ); + Vec_WecPush( &p->vOccurs, Lit, i ); + } +} +void Pla_ManConvertToBits( Pla_Man_t * p ) +{ + Vec_Int_t * vCube; int i, k, Lit; + Vec_IntFillNatural( &p->vCubes, Vec_WecSize(&p->vLits) ); + Vec_WrdFill( &p->vInBits, Pla_ManCubeNum(p) * p->nInWords, 0 ); + Vec_WecForEachLevel( &p->vLits, vCube, i ) + Vec_IntForEachEntry( vCube, Lit, k ) + Pla_CubeSetLit( Pla_CubeIn(p, i), Abc_Lit2Var(Lit), Abc_LitIsCompl(Lit) ? PLA_LIT_ZERO : PLA_LIT_ONE ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManDist1Num( Pla_Man_t * p ) +{ + word * pCube1, * pCube2; + int i, k, Dist, Count = 0; + Pla_ForEachCubeIn( p, pCube1, i ) + Pla_ForEachCubeInStart( p, pCube2, k, i+1 ) + { + Dist = Pla_CubesAreDistance1( pCube1, pCube2, p->nInWords ); +// Dist = Pla_CubesAreConsensus( pCube1, pCube2, p->nInWords, NULL ); + Count += (Dist == 1); + } + return Count; +} +int Pla_ManDist1NumTest( Pla_Man_t * p ) +{ + abctime clk = Abc_Clock(); + int Count = Pla_ManDist1Num( p ); + printf( "Found %d pairs among %d cubes using cube pair enumeration. ", Count, Pla_ManCubeNum(p) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/pla/plaMerge.c b/src/base/pla/plaMerge.c new file mode 100644 index 00000000..b990821b --- /dev/null +++ b/src/base/pla/plaMerge.c @@ -0,0 +1,55 @@ +/**CFile**************************************************************** + + FileName [plaMerge.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: plaMerge.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pla.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Pla_ManDist1Merge( Pla_Man_t * p ) +{ + return 0; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/pla/plaRead.c b/src/base/pla/plaRead.c new file mode 100644 index 00000000..74d79618 --- /dev/null +++ b/src/base/pla/plaRead.c @@ -0,0 +1,224 @@ +/**CFile**************************************************************** + + FileName [plaRead.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: plaRead.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pla.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Pla_ReadFile( char * pFileName, char ** ppLimit ) +{ + char * pBuffer; + int nFileSize, RetValue; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open input file.\n" ); + return NULL; + } + // get the file size, in bytes + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + // move the file current reading position to the beginning + rewind( pFile ); + // load the contents of the file into memory + pBuffer = ABC_ALLOC( char, nFileSize + 16 ); + pBuffer[0] = '\n'; + RetValue = fread( pBuffer+1, nFileSize, 1, pFile ); + fclose( pFile ); + // terminate the string with '\0' + pBuffer[nFileSize + 1] = '\n'; + pBuffer[nFileSize + 2] = '\0'; + *ppLimit = pBuffer + nFileSize + 3; + return pBuffer; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Pla_ReadPlaRemoveComments( char * pBuffer, char * pLimit ) +{ + char * pTemp; + for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ ) + if ( *pTemp == '#' ) + while ( *pTemp && *pTemp != '\n' ) + *pTemp++ = ' '; +} +int Pla_ReadPlaHeader( char * pBuffer, char * pLimit, int * pnIns, int * pnOuts, int * pnCubes, int * pType ) +{ + char * pTemp; + *pType = PLA_FILE_FD; + *pnIns = *pnOuts = *pnCubes = -1; + for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ ) + { + if ( *pTemp != '.' ) + continue; + if ( !strncmp(pTemp, ".i ", 3) ) + *pnIns = atoi( pTemp + 3 ); + else if ( !strncmp(pTemp, ".o ", 3) ) + *pnOuts = atoi( pTemp + 3 ); + else if ( !strncmp(pTemp, ".p ", 3) ) + *pnCubes = atoi( pTemp + 3 ); + else if ( !strncmp(pTemp, ".e ", 3) ) + break; + else if ( !strncmp(pTemp, ".type ", 6) ) + { + char Buffer[100]; + *pType = PLA_FILE_NONE; + sscanf( pTemp+6, "%s", Buffer ); + if ( !strcmp(Buffer, "f") ) + *pType = PLA_FILE_F; + else if ( !strcmp(Buffer, "fr") ) + *pType = PLA_FILE_FR; + else if ( !strcmp(Buffer, "fd") ) + *pType = PLA_FILE_FD; + else if ( !strcmp(Buffer, "fdr") ) + *pType = PLA_FILE_FDR; + } + } + if ( *pnIns <= 0 ) + printf( "The number of inputs (.i) should be positive.\n" ); + if ( *pnOuts <= 0 ) + printf( "The number of outputs (.o) should be positive.\n" ); + return *pnIns > 0 && *pnOuts > 0; +} +Vec_Str_t * Pla_ReadPlaBody( char * pBuffer, char * pLimit, Pla_File_t Type ) +{ + char * pTemp; + Vec_Str_t * vLits; + vLits = Vec_StrAlloc( 10000 ); + for ( pTemp = pBuffer; pTemp < pLimit; pTemp++ ) + { + if ( *pTemp == '.' ) + while ( *pTemp && *pTemp != '\n' ) + pTemp++; + if ( *pTemp == '0' ) + Vec_StrPush( vLits, (char)PLA_LIT_ZERO ); + else if ( *pTemp == '1' ) + Vec_StrPush( vLits, (char)PLA_LIT_ONE ); + else if ( *pTemp == '-' || *pTemp == '2' ) + Vec_StrPush( vLits, (char)PLA_LIT_DASH ); + else if ( *pTemp == '~' ) // no meaning + { + if ( Type == PLA_FILE_F || Type == PLA_FILE_FD ) + Vec_StrPush( vLits, (char)PLA_LIT_ZERO ); + else if ( Type == PLA_FILE_FR ) + Vec_StrPush( vLits, (char)PLA_LIT_DASH ); + else if ( Type == PLA_FILE_FDR ) + Vec_StrPush( vLits, (char)PLA_LIT_FULL ); + else assert( 0 ); + } + } + return vLits; +} +void Pla_ReadAddBody( Pla_Man_t * p, Vec_Str_t * vLits ) +{ + word * pCubeIn, * pCubeOut; + int i, k, Lit, Count = 0; + int nCubesReal = Vec_StrSize(vLits) / (p->nIns + p->nOuts); + assert( Vec_StrSize(vLits) % (p->nIns + p->nOuts) == 0 ); + if ( nCubesReal != Pla_ManCubeNum(p) ) + { + printf( "Warning: Declared number of cubes (%d) differs from the actual (%d).\n", + Pla_ManCubeNum(p), nCubesReal ); + if ( nCubesReal < Pla_ManCubeNum(p) ) + Vec_IntShrink( &p->vCubes, nCubesReal ); + else + { + assert( nCubesReal > Pla_ManCubeNum(p) ); + Vec_IntFillNatural( &p->vCubes, nCubesReal ); + Vec_WrdFillExtra( &p->vInBits, nCubesReal * p->nInWords, 0 ); + Vec_WrdFillExtra( &p->vOutBits, nCubesReal * p->nOutWords, 0 ); + } + } + Pla_ForEachCubeInOut( p, pCubeIn, pCubeOut, i ) + { + Pla_CubeForEachLit( p->nIns, pCubeIn, Lit, k ) + Pla_CubeSetLit( pCubeIn, k, (int)Vec_StrEntry(vLits, Count++) ); + Pla_CubeForEachLit( p->nOuts, pCubeOut, Lit, k ) + Pla_CubeSetLit( pCubeOut, k, (int)Vec_StrEntry(vLits, Count++) ); + } + assert( Count == Vec_StrSize(vLits) ); +} +Pla_Man_t * Pla_ReadPla( char * pFileName ) +{ + Pla_Man_t * p; + Vec_Str_t * vLits; + int nIns, nOuts, nCubes, Type; + char * pBuffer, * pLimit; + pBuffer = Pla_ReadFile( pFileName, &pLimit ); + if ( pBuffer == NULL ) + return NULL; + Pla_ReadPlaRemoveComments( pBuffer, pLimit ); + if ( Pla_ReadPlaHeader( pBuffer, pLimit, &nIns, &nOuts, &nCubes, &Type ) ) + { + vLits = Pla_ReadPlaBody( pBuffer, pLimit, Type ); + if ( Vec_StrSize(vLits) % (nIns + nOuts) == 0 ) + { + if ( nCubes == -1 ) + nCubes = Vec_StrSize(vLits) / (nIns + nOuts); + p = Pla_ManAlloc( pFileName, nIns, nOuts, nCubes ); + p->Type = Type; + Pla_ReadAddBody( p, vLits ); + Vec_StrFree( vLits ); + ABC_FREE( pBuffer ); + return p; + } + printf( "Literal count is incorrect (in = %d; out = %d; lit = %d).\n", nIns, nOuts, Vec_StrSize(vLits) ); + Vec_StrFree( vLits ); + } + ABC_FREE( pBuffer ); + return NULL; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/pla/plaWrite.c b/src/base/pla/plaWrite.c new file mode 100644 index 00000000..ed301e87 --- /dev/null +++ b/src/base/pla/plaWrite.c @@ -0,0 +1,112 @@ +/**CFile**************************************************************** + + FileName [plaWrite.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: plaWrite.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "pla.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Pla_WritePlaInt( Pla_Man_t * p ) +{ + Vec_Str_t * vOut = Vec_StrAlloc( 10000 ); + char * pLits = "-01?"; + word * pCubeIn, * pCubeOut; + int i, k, Lit; + // write comments + Vec_StrPrintStr( vOut, "# SOP \"" ); + Vec_StrPrintStr( vOut, p->pName ); + Vec_StrPrintStr( vOut, "\" written via PLA package in ABC on " ); + Vec_StrPrintStr( vOut, Extra_TimeStamp() ); + Vec_StrPrintStr( vOut, "\n\n" ); + // write header + if ( p->Type != PLA_FILE_FD ) + { + if ( p->Type == PLA_FILE_F ) + Vec_StrPrintStr( vOut, ".type f\n" ); + else if ( p->Type == PLA_FILE_FR ) + Vec_StrPrintStr( vOut, ".type fr\n" ); + else if ( p->Type == PLA_FILE_FDR ) + Vec_StrPrintStr( vOut, ".type fdr\n" ); + else if ( p->Type == PLA_FILE_NONE ) + Vec_StrPrintStr( vOut, ".type ???\n" ); + } + Vec_StrPrintStr( vOut, ".i " ); + Vec_StrPrintNum( vOut, p->nIns ); + Vec_StrPrintStr( vOut, "\n.o " ); + Vec_StrPrintNum( vOut, p->nOuts ); + Vec_StrPrintStr( vOut, "\n.p " ); + Vec_StrPrintNum( vOut, Pla_ManCubeNum(p) ); + Vec_StrPrintStr( vOut, "\n" ); + // write cube + Pla_ForEachCubeInOut( p, pCubeIn, pCubeOut, i ) + { + Pla_CubeForEachLit( p->nIns, pCubeIn, Lit, k ) + Vec_StrPush( vOut, pLits[Lit] ); + Vec_StrPush( vOut, ' ' ); + Pla_CubeForEachLit( p->nOuts, pCubeOut, Lit, k ) + Vec_StrPush( vOut, pLits[Lit] ); + Vec_StrPush( vOut, '\n' ); + } + Vec_StrPrintStr( vOut, ".e\n\n\0" ); + return vOut; +} +void Pla_WritePla( Pla_Man_t * p, char * pFileName ) +{ + Vec_Str_t * vOut = Pla_WritePlaInt( p ); + if ( Vec_StrSize(vOut) > 0 ) + { + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + else + { + fwrite( Vec_StrArray(vOut), 1, Vec_StrSize(vOut), pFile ); + fclose( pFile ); + } + } + Vec_StrFreeP( &vOut ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wlc/wlcReadSmt.c b/src/base/wlc/wlcReadSmt.c index dcf018b7..fff760ec 100644 --- a/src/base/wlc/wlcReadSmt.c +++ b/src/base/wlc/wlcReadSmt.c @@ -709,6 +709,7 @@ static inline char * Smt_PrsLoadFile( char * pFileName, char ** ppLimit ) pBuffer = ABC_ALLOC( char, nFileSize + 16 ); pBuffer[0] = '\n'; RetValue = fread( pBuffer+1, nFileSize, 1, pFile ); + fclose( pFile ); // terminate the string with '\0' pBuffer[nFileSize + 1] = '\n'; pBuffer[nFileSize + 2] = '\0'; diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index b1aa556b..6d3ea8f6 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -573,6 +573,14 @@ static inline void Vec_IntFillTwo( Vec_Int_t * p, int nSize, int FillEven, int F p->pArray[i] = (i & 1) ? FillOdd : FillEven; p->nSize = nSize; } +static inline void Vec_IntFillNatural( Vec_Int_t * p, int nSize ) +{ + int i; + Vec_IntGrow( p, nSize ); + for ( i = 0; i < nSize; i++ ) + p->pArray[i] = i; + p->nSize = nSize; +} /**Function************************************************************* |