From ada21a655f9a6f04b13a5f90758a7b64ab72f221 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Jun 2016 15:22:03 -0700 Subject: New multi-output PLA reader and preprocessor (read_plamo). --- src/base/io/io.c | 52 ++++++ src/base/io/ioReadPlaMo.c | 438 ++++++++++++++++++++++++++++++++++++++++++++++ src/base/io/module.make | 1 + 3 files changed, 491 insertions(+) create mode 100644 src/base/io/ioReadPlaMo.c (limited to 'src/base') diff --git a/src/base/io/io.c b/src/base/io/io.c index a5a64db6..f5f4c341 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -43,6 +43,7 @@ static int IoCommandReadEqn ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadFins ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadInit ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadPla ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandReadPlaMo ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadTruth ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadVerilog ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandReadStatus ( Abc_Frame_t * pAbc, int argc, char **argv ); @@ -108,6 +109,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "read_fins", IoCommandReadFins, 0 ); Cmd_CommandAdd( pAbc, "I/O", "read_init", IoCommandReadInit, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_pla", IoCommandReadPla, 1 ); + Cmd_CommandAdd( pAbc, "I/O", "read_plamo", IoCommandReadPlaMo, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_truth", IoCommandReadTruth, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_verilog", IoCommandReadVerilog, 1 ); Cmd_CommandAdd( pAbc, "I/O", "read_status", IoCommandReadStatus, 0 ); @@ -1028,6 +1030,56 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IoCommandReadPlaMo( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Abc_Ntk_t * Mop_ManTest( char * pFileName, int fVerbose ); + Abc_Ntk_t * pNtk; + 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 ) + goto usage; + // get the input file name + pNtk = Mop_ManTest( argv[globalUtilOptind], fVerbose ); + if ( pNtk == NULL ) + return 1; + // replace the current network + Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); + Abc_FrameClearVerifStatus( pAbc ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: read_plamo [-vh] \n" ); + fprintf( pAbc->Err, "\t reads the network in multi-output PLA\n" ); + fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes":"no" ); + fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); + fprintf( pAbc->Err, "\tfile : the name of a file to read\n" ); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/io/ioReadPlaMo.c b/src/base/io/ioReadPlaMo.c new file mode 100644 index 00000000..1294768b --- /dev/null +++ b/src/base/io/ioReadPlaMo.c @@ -0,0 +1,438 @@ +/**CFile**************************************************************** + + FileName [ioReadPlaMo.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Procedure to read network from file.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ioReadPlaMo.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ioAbc.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Mop_Man_t_ Mop_Man_t; +struct Mop_Man_t_ +{ + int nIns; + int nOuts; + int nWordsIn; + int nWordsOut; + Vec_Wrd_t * vWordsIn; + Vec_Wrd_t * vWordsOut; + Vec_Int_t * vCubes; +}; + +static inline int Mop_ManIsSopSymb( char c ) { return c == '0' || c == '1' || c == '-'; } +static inline int Mop_ManIsSpace( char c ) { return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; } + +static inline word * Mop_ManCubeIn( Mop_Man_t * p, int i ) { return Vec_WrdEntryP(p->vWordsIn, p->nWordsIn * i); } +static inline word * Mop_ManCubeOut( Mop_Man_t * p, int i ) { return Vec_WrdEntryP(p->vWordsOut, p->nWordsOut * i); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Mop_Man_t * Mop_ManAlloc( int nIns, int nOuts, int nCubes ) +{ + Mop_Man_t * p = ABC_CALLOC( Mop_Man_t, 1 ); + p->nIns = nIns; + p->nOuts = nOuts; + p->nWordsIn = Abc_Bit6WordNum( 2*nIns ); + p->nWordsOut = Abc_Bit6WordNum( nOuts ); + p->vWordsIn = Vec_WrdStart( p->nWordsIn * nCubes ); + p->vWordsOut = Vec_WrdStart( p->nWordsOut * nCubes ); + p->vCubes = Vec_IntAlloc( nCubes ); + return p; +} +void Mop_ManStop( Mop_Man_t * p ) +{ + Vec_WrdFree( p->vWordsIn ); + Vec_WrdFree( p->vWordsOut ); + Vec_IntFree( p->vCubes ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Reads the file into a character buffer.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Mop_ManLoadFile( char * pFileName ) +{ + FILE * pFile; + int nFileSize, RetValue; + char * pContents; + pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + Abc_Print( -1, "Mop_ManLoadFile(): The file is unavailable (absent or open).\n" ); + return NULL; + } + fseek( pFile, 0, SEEK_END ); + nFileSize = ftell( pFile ); + if ( nFileSize == 0 ) + { + Abc_Print( -1, "Mop_ManLoadFile(): The file is empty.\n" ); + return NULL; + } + pContents = ABC_ALLOC( char, nFileSize + 10 ); + rewind( pFile ); + RetValue = fread( pContents, nFileSize, 1, pFile ); + fclose( pFile ); + strcpy( pContents + nFileSize, "\n" ); + return pContents; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Mop_ManReadParams( char * pBuffer, int * pnIns, int * pnOuts ) +{ + char * pIns = strstr( pBuffer, ".i " ); + char * pOuts = strstr( pBuffer, ".o " ); + char * pStr = pBuffer; int nCubes = 0; + if ( pIns == NULL || pOuts == NULL ) + return -1; + *pnIns = atoi( pIns + 2 ); + *pnOuts = atoi( pOuts + 2 ); + while ( *pStr ) + nCubes += (*pStr++ == '\n'); + return nCubes; +} +Mop_Man_t * Mop_ManRead( char * pFileName ) +{ + Mop_Man_t * p; + int nIns, nOuts, nCubes, iCube; + char * pToken, * pBuffer = Mop_ManLoadFile( pFileName ); + if ( pBuffer == NULL ) + return NULL; + nCubes = Mop_ManReadParams( pBuffer, &nIns, &nOuts ); + if ( nCubes == -1 ) + return NULL; + p = Mop_ManAlloc( nIns, nOuts, nCubes ); + // get the first cube + pToken = strtok( pBuffer, "\n" ); + while ( pToken ) + { + while ( Mop_ManIsSpace(*pToken) ) + pToken++; + if ( Mop_ManIsSopSymb(*pToken) ) + break; + pToken = strtok( NULL, "\n" ); + } + // read cubes + for ( iCube = 0; pToken && Mop_ManIsSopSymb(*pToken); iCube++ ) + { + char * pTokenCopy = pToken; + int i, o, nVars[2] = {nIns, nOuts}; + word * pCube[2] = { Mop_ManCubeIn(p, iCube), Mop_ManCubeOut(p, iCube) }; + for ( o = 0; o < 2; o++ ) + { + while ( Mop_ManIsSpace(*pToken) ) + pToken++; + for ( i = 0; i < nVars[o]; i++, pToken++ ) + { + if ( !Mop_ManIsSopSymb(*pToken) ) + { + printf( "Cannot read cube %d (%s).\n", iCube+1, pTokenCopy ); + ABC_FREE( pBuffer ); + Mop_ManStop( p ); + return NULL; + } + if ( o == 1 ) + { + if ( *pToken == '1' ) + Abc_TtSetBit( pCube[o], i ); + } + else if ( *pToken == '0' ) + Abc_TtSetBit( pCube[o], 2*i ); + else if ( *pToken == '1' ) + Abc_TtSetBit( pCube[o], 2*i+1 ); + } + } + assert( iCube < nCubes ); + Vec_IntPush( p->vCubes, iCube ); + pToken = strtok( NULL, "\n" ); + } + ABC_FREE( pBuffer ); + return p; +} +void Mop_ManPrint( Mop_Man_t * p ) +{ + int i, k, iCube; + printf( ".%d\n", p->nIns ); + printf( ".%d\n", p->nOuts ); + Vec_IntForEachEntry( p->vCubes, iCube, i ) + { + char Symb[4] = { '-', '0', '1', '?' }; + word * pCubeIn = Mop_ManCubeIn( p, iCube ); + word * pCubeOut = Mop_ManCubeOut( p, iCube ); + for ( k = 0; k < p->nIns; k++ ) + printf( "%c", Symb[Abc_TtGetQua(pCubeIn, k)] ); + printf( " " ); + for ( k = 0; k < p->nOuts; k++ ) + printf( "%d", Abc_TtGetBit(pCubeOut, k) ); + printf( "\n" ); + } + printf( ".e\n" ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Mop_ManCountOnes( word * pCube, int nWords ) +{ + int w, Count = 0; + for ( w = 0; w < nWords; w++ ) + Count += Abc_TtCountOnes( pCube[w] ); + return Count; +} +static inline int Mop_ManCountOutputLits( Mop_Man_t * p ) +{ + int i, iCube, nOutLits = 0; + Vec_IntForEachEntry( p->vCubes, iCube, i ) + nOutLits += Mop_ManCountOnes( Mop_ManCubeOut(p, iCube), p->nWordsOut ); + return nOutLits; +} +static inline Vec_Wec_t * Mop_ManCreateGroups( Mop_Man_t * p ) +{ + int i, iCube; + Vec_Wec_t * vGroups = Vec_WecStart( p->nIns ); + Vec_IntForEachEntry( p->vCubes, iCube, i ) + Vec_WecPush( vGroups, Mop_ManCountOnes(Mop_ManCubeIn(p, iCube), p->nWordsIn), iCube ); + return vGroups; +} +static inline int Mop_ManCheckContain( word * pBig, word * pSmall, int nWords ) +{ + int w; + for ( w = 0; w < nWords; w++ ) + if ( pSmall[w] != (pSmall[w] & pBig[w]) ) + return 0; + return 1; +} +void Mop_ManReduce( Mop_Man_t * p ) +{ + abctime clk = Abc_Clock(); + Vec_Int_t * vGroup, * vGroup2; + int w, i, k, c1, c2, iCube1, iCube2; + int nOutLits, nOutLits2, nEqual = 0, nContain = 0; + Vec_Wec_t * vGroups = Mop_ManCreateGroups( p ); + nOutLits = Mop_ManCountOutputLits( p ); + // check identical cubes within each group + Vec_WecForEachLevel( vGroups, vGroup, i ) + { + Vec_IntForEachEntry( vGroup, iCube1, c1 ) + if ( iCube1 != -1 ) + { + word * pCube1Out, * pCube1 = Mop_ManCubeIn( p, iCube1 ); + Vec_IntForEachEntryStart( vGroup, iCube2, c2, c1+1 ) + if ( iCube2 != -1 ) + { + word * pCube2Out, * pCube2 = Mop_ManCubeIn( p, iCube2 ); + if ( memcmp(pCube1, pCube2, sizeof(word)*p->nWordsIn) ) + continue; + // merge cubes + pCube1Out = Mop_ManCubeOut( p, iCube1 ); + pCube2Out = Mop_ManCubeOut( p, iCube2 ); + for ( w = 0; w < p->nWordsOut; w++ ) + pCube1Out[w] |= pCube2Out[w]; + Vec_IntWriteEntry( vGroup, c2, -1 ); + nEqual++; + } + } + } + // check contained cubes + Vec_WecForEachLevel( vGroups, vGroup, i ) + { + // compare cubes in vGroup with cubes containing more literals + Vec_WecForEachLevelStart( vGroups, vGroup2, k, i+1 ) + { + Vec_IntForEachEntry( vGroup, iCube1, c1 ) + if ( iCube1 != -1 ) + { + word * pCube1Out, * pCube1 = Mop_ManCubeIn( p, iCube1 ); + Vec_IntForEachEntry( vGroup2, iCube2, c2 ) + if ( iCube2 != -1 ) + { + word * pCube2Out, * pCube2 = Mop_ManCubeIn( p, iCube2 ); + if ( !Mop_ManCheckContain(pCube2, pCube1, p->nWordsIn) ) + continue; + pCube1Out = Mop_ManCubeOut( p, iCube1 ); + pCube2Out = Mop_ManCubeOut( p, iCube2 ); + for ( w = 0; w < p->nWordsOut; w++ ) + pCube2Out[w] &= ~pCube1Out[w]; + for ( w = 0; w < p->nWordsOut; w++ ) + if ( pCube2Out[w] ) + break; + if ( w < p->nWordsOut ) // has output literals + continue; + // remove larger cube + Vec_IntWriteEntry( vGroup2, c2, -1 ); + nContain++; + } + } + } + } + nOutLits2 = Mop_ManCountOutputLits( p ); + // reload cubes + Vec_IntClear( p->vCubes ); + Vec_WecForEachLevel( vGroups, vGroup, i ) + Vec_IntForEachEntry( vGroup, iCube1, c1 ) + if ( iCube1 != -1 ) + Vec_IntPush( p->vCubes, iCube1 ); + Vec_WecFree( vGroups ); + + printf( "Reduced %d equal and %d contained cubes. Output lits: %d -> %d. ", nEqual, nContain, nOutLits, nOutLits2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t * Mop_ManCubeCount( Mop_Man_t * p ) +{ + int i, k, iCube; + Vec_Wec_t * vOuts = Vec_WecStart( p->nOuts ); + Vec_IntForEachEntry( p->vCubes, iCube, i ) + if ( iCube != -1 ) + { + word * pCube = Mop_ManCubeOut( p, iCube ); + for ( k = 0; k < p->nOuts; k++ ) + if ( Abc_TtGetBit( pCube, k ) ) + Vec_WecPush( vOuts, k, iCube ); + } + return vOuts; +} +Abc_Ntk_t * Mop_ManDerive( Mop_Man_t * p, char * pFileName ) +{ + int i, k, c, iCube; + char Symb[4] = { '-', '0', '1', '?' }; // cube symbols + Vec_Str_t * vSop = Vec_StrAlloc( 1000 ); // storage for one SOP + Vec_Wec_t * vOuts = Mop_ManCubeCount( p ); // cube count for each output + Abc_Ntk_t * pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); + pNtk->pName = Extra_UtilStrsav( pFileName ); + pNtk->pSpec = Extra_UtilStrsav( pFileName ); + for ( i = 0; i < p->nIns; i++ ) + Abc_NtkCreatePi(pNtk); + for ( i = 0; i < p->nOuts; i++ ) + { + Vec_Int_t * vThis = Vec_WecEntry( vOuts, i ); + Abc_Obj_t * pPo = Abc_NtkCreatePo(pNtk); + Abc_Obj_t * pNode = Abc_NtkCreateNode(pNtk); + Abc_ObjAddFanin( pPo, pNode ); + if ( Vec_IntSize(vThis) == 0 ) + { + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ); + continue; + } + for ( k = 0; k < p->nIns; k++ ) + Abc_ObjAddFanin( pNode, Abc_NtkPi(pNtk, k) ); + Vec_StrClear( vSop ); + Vec_IntForEachEntry( vThis, iCube, c ) + { + word * pCube = Mop_ManCubeIn( p, iCube ); + for ( k = 0; k < p->nIns; k++ ) + Vec_StrPush( vSop, Symb[Abc_TtGetQua(pCube, k)] ); + Vec_StrAppend( vSop, " 1\n" ); + } + Vec_StrPush( vSop, '\0' ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, Vec_StrArray(vSop) ); + } + Vec_StrFree( vSop ); + Vec_WecFree( vOuts ); + Abc_NtkAddDummyPiNames( pNtk ); + Abc_NtkAddDummyPoNames( pNtk ); + return pNtk; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Mop_ManTest( char * pFileName, int fVerbose ) +{ + Abc_Ntk_t * pNtk = NULL; + Mop_Man_t * p = Mop_ManRead( pFileName ); + if ( p == NULL ) + return NULL; + //Mop_ManPrint( p ); + Mop_ManReduce( p ); + //Mop_ManPrint( p ); + pNtk = Mop_ManDerive( p, pFileName ); + Mop_ManStop( p ); + return pNtk; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/io/module.make b/src/base/io/module.make index dee459da..b3fcc198 100644 --- a/src/base/io/module.make +++ b/src/base/io/module.make @@ -10,6 +10,7 @@ SRC += src/base/io/io.c \ src/base/io/ioReadEdif.c \ src/base/io/ioReadEqn.c \ src/base/io/ioReadPla.c \ + src/base/io/ioReadPlaMo.c \ src/base/io/ioReadVerilog.c \ src/base/io/ioUtil.c \ src/base/io/ioWriteAiger.c \ -- cgit v1.2.3