summaryrefslogtreecommitdiffstats
path: root/src/base/wlc/wlcReadVer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/wlc/wlcReadVer.c')
-rw-r--r--src/base/wlc/wlcReadVer.c711
1 files changed, 711 insertions, 0 deletions
diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c
new file mode 100644
index 00000000..cf880cd5
--- /dev/null
+++ b/src/base/wlc/wlcReadVer.c
@@ -0,0 +1,711 @@
+/**CFile****************************************************************
+
+ FileName [wlcReadVer.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Verilog parser.]
+
+ Synopsis [Parses several flavors of word-level Verilog.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - August 22, 2014.]
+
+ Revision [$Id: wlcReadVer.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "wlc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// Word-level Verilog file parser
+#define WLV_PRS_MAX_LINE 1000
+
+typedef struct Wlc_Prs_t_ Wlc_Prs_t;
+struct Wlc_Prs_t_
+{
+ int nFileSize;
+ char * pFileName;
+ char * pBuffer;
+ Vec_Int_t * vLines;
+ Vec_Int_t * vStarts;
+ Vec_Int_t * vFanins;
+ Wlc_Ntk_t * pNtk;
+ char sError[WLV_PRS_MAX_LINE];
+};
+
+static inline int Wlc_PrsOffset( Wlc_Prs_t * p, char * pStr ) { return pStr - p->pBuffer; }
+static inline char * Wlc_PrsStr( Wlc_Prs_t * p, int iOffset ) { return p->pBuffer + iOffset; }
+static inline int Wlc_PrsStrCmp( char * pStr, char * pWhat ) { return !strncmp( pStr, pWhat, strlen(pWhat)); }
+
+#define Wlc_PrsForEachLine( p, pLine, i ) \
+ for ( i = 0; (i < Vec_IntSize((p)->vStarts)) && ((pLine) = Wlc_PrsStr(p, Vec_IntEntry((p)->vStarts, i))); i++ )
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Wlc_Prs_t * Wlc_PrsStart( char * pFileName )
+{
+ Wlc_Prs_t * p;
+ if ( !Extra_FileCheck( pFileName ) )
+ return NULL;
+ p = ABC_CALLOC( Wlc_Prs_t, 1 );
+ p->pFileName = pFileName;
+ p->pBuffer = Extra_FileReadContents( pFileName );
+ p->nFileSize = strlen(p->pBuffer); assert( p->nFileSize > 0 );
+ p->vLines = Vec_IntAlloc( p->nFileSize / 50 );
+ p->vStarts = Vec_IntAlloc( p->nFileSize / 50 );
+ p->vFanins = Vec_IntAlloc( 100 );
+ return p;
+}
+void Wlc_PrsStop( Wlc_Prs_t * p )
+{
+ if ( p->pNtk )
+ Wlc_NtkFree( p->pNtk );
+ Vec_IntFree( p->vLines );
+ Vec_IntFree( p->vStarts );
+ Vec_IntFree( p->vFanins );
+ ABC_FREE( p->pBuffer );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the error message including the file name and line number.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Wlc_PrsWriteErrorMessage( Wlc_Prs_t * p, char * pCur, const char * format, ... )
+{
+ char * pMessage;
+ // derive message
+ va_list args;
+ va_start( args, format );
+ pMessage = vnsprintf( format, args );
+ va_end( args );
+ // print messsage
+ assert( strlen(pMessage) < WLV_PRS_MAX_LINE - 100 );
+ assert( p->sError[0] == 0 );
+ if ( pCur == NULL ) // the line number is not given
+ sprintf( p->sError, "%s: %s\n", p->pFileName, pMessage );
+ else // print the error message with the line number
+ {
+ int Entry, iLine = 0;
+ Vec_IntForEachEntry( p->vLines, Entry, iLine )
+ if ( Entry > pCur - p->pBuffer )
+ break;
+ sprintf( p->sError, "%s (line %d): %s\n", p->pFileName, iLine+1, pMessage );
+ }
+ free( pMessage );
+ return 0;
+}
+void Wlc_PrsPrintErrorMessage( Wlc_Prs_t * p )
+{
+ if ( p->sError[0] == 0 )
+ return;
+ fprintf( stdout, "%s", p->sError );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Wlc_PrsIsDigit( char * pStr )
+{
+ return (pStr[0] >= '0' && pStr[0] <= '9');
+}
+static inline int Wlc_PrsIsChar( char * pStr )
+{
+ return (pStr[0] >= 'a' && pStr[0] <= 'z') ||
+ (pStr[0] >= 'A' && pStr[0] <= 'Z') ||
+ (pStr[0] >= '0' && pStr[0] <= '9') ||
+ pStr[0] == '_' || pStr[0] == '$';
+}
+static inline char * Wlc_PrsSkipSpaces( char * pStr )
+{
+ while ( *pStr && *pStr == ' ' )
+ pStr++;
+ return pStr;
+}
+static inline char * Wlc_PrsFindSymbol( char * pStr, char Symb )
+{
+ for ( ; *pStr; pStr++ )
+ if ( *pStr == Symb )
+ return pStr;
+ return NULL;
+}
+static inline char * Wlc_PrsFindSymbolTwo( char * pStr, char Symb, char Symb2 )
+{
+ for ( ; pStr[1]; pStr++ )
+ if ( pStr[0] == Symb && pStr[1] == Symb2 )
+ return pStr;
+ return NULL;
+}
+static inline char * Wlc_PrsFindClosingParanthesis( char * pStr, char Open, char Close )
+{
+ int Counter = 0;
+ int fNotName = 1;
+ assert( *pStr == Open );
+ for ( ; *pStr; pStr++ )
+ {
+ if ( fNotName )
+ {
+ if ( *pStr == Open )
+ Counter++;
+ if ( *pStr == Close )
+ Counter--;
+ if ( Counter == 0 )
+ return pStr;
+ }
+ if ( *pStr == '\\' )
+ fNotName = 0;
+ else if ( !fNotName && *pStr == ' ' )
+ fNotName = 1;
+ }
+ return NULL;
+}
+int Wlc_PrsRemoveComments( Wlc_Prs_t * p )
+{
+ int fSpecifyFound = 0;
+ char * pCur, * pNext, * pEnd = p->pBuffer + p->nFileSize;
+ for ( pCur = p->pBuffer; pCur < pEnd; pCur++ )
+ {
+ // regular comment (//)
+ if ( *pCur == '/' && pCur[1] == '/' )
+ {
+ if ( pCur + 5 < pEnd && pCur[2] == 'a' && pCur[3] == 'b' && pCur[4] == 'c' && pCur[5] == '2' )
+ pCur[0] = pCur[1] = pCur[2] = pCur[3] = pCur[4] = pCur[5] = ' ';
+ else
+ {
+ pNext = Wlc_PrsFindSymbol( pCur, '\n' );
+ if ( pNext == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find end-of-line after symbols \"//\"." );
+ for ( ; pCur < pNext; pCur++ )
+ *pCur = ' ';
+ }
+ }
+ // skip preprocessor directive (`timescale, `celldefine, etc)
+ else if ( *pCur == '`' )
+ {
+ pNext = Wlc_PrsFindSymbol( pCur, '\n' );
+ if ( pNext == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find end-of-line after symbols \"`\"." );
+ for ( ; pCur < pNext; pCur++ )
+ *pCur = ' ';
+ }
+ // regular comment (/* ... */)
+ else if ( *pCur == '/' && pCur[1] == '*' )
+ {
+ pNext = Wlc_PrsFindSymbolTwo( pCur, '*', '/' );
+ if ( pNext == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find symbols \"*/\" after symbols \"/*\"." );
+ // overwrite comment
+ for ( ; pCur < pNext + 2; pCur++ )
+ *pCur = ' ';
+ }
+ // 'specify' treated as comments
+ else if ( *pCur == 's' && pCur[1] == 'p' && pCur[2] == 'e' && !strncmp(pCur, "specify", 7) )
+ {
+ for ( pNext = pCur; pNext < pEnd - 10; pNext++ )
+ if ( *pNext == 'e' && pNext[1] == 'n' && pNext[2] == 'd' && !strncmp(pNext, "endspecify", 10) )
+ {
+ // overwrite comment
+ for ( ; pCur < pNext + 10; pCur++ )
+ *pCur = ' ';
+ if ( fSpecifyFound == 0 )
+ Abc_Print( 0, "Ignoring specify/endspecify directives.\n" );
+ fSpecifyFound = 1;
+ break;
+ }
+ }
+ // insert semicolons
+ else if ( *pCur == 'e' && pCur[1] == 'n' && pCur[2] == 'd' && !strncmp(pCur, "endmodule", 9) )
+ pCur[strlen("endmodule")] = ';';
+ // overwrite end-of-lines with spaces (less checking to do later on)
+ if ( *pCur == '\n' || *pCur == '\r' || *pCur == '\t' )
+ *pCur = ' ';
+ }
+ return 1;
+}
+int Wlc_PrsPrepare( Wlc_Prs_t * p )
+{
+ int fPrettyPrint = 0;
+ int fNotName = 1;
+ char * pTemp, * pPrev, * pThis;
+ // collect info about lines
+ assert( Vec_IntSize(p->vLines) == 0 );
+ for ( pTemp = p->pBuffer; *pTemp; pTemp++ )
+ if ( *pTemp == '\n' )
+ Vec_IntPush( p->vLines, pTemp - p->pBuffer );
+ // delete comments and insert breaks
+ if ( !Wlc_PrsRemoveComments( p ) )
+ return 0;
+ // collect info about breaks
+ assert( Vec_IntSize(p->vStarts) == 0 );
+ for ( pPrev = pThis = p->pBuffer; *pThis; pThis++ )
+ {
+ if ( fNotName && *pThis == ';' )
+ {
+ *pThis = 0;
+ Vec_IntPush( p->vStarts, Wlc_PrsOffset(p, Wlc_PrsSkipSpaces(pPrev)) );
+ pPrev = pThis + 1;
+ }
+ if ( *pThis == '\\' )
+ fNotName = 0;
+ else if ( !fNotName && *pThis == ' ' )
+ fNotName = 1;
+ }
+
+ if ( fPrettyPrint )
+ {
+ int i, k;
+ // print the line types
+ Wlc_PrsForEachLine( p, pTemp, i )
+ {
+ if ( Wlc_PrsStrCmp( pTemp, "module" ) )
+ printf( "\n" );
+ if ( !Wlc_PrsStrCmp( pTemp, "module" ) && !Wlc_PrsStrCmp( pTemp, "endmodule" ) )
+ printf( " " );
+ printf( "%c", pTemp[0] );
+ for ( k = 1; pTemp[k]; k++ )
+ if ( pTemp[k] != ' ' || pTemp[k-1] != ' ' )
+ printf( "%c", pTemp[k] );
+ printf( ";\n" );
+ }
+/*
+ // print the line types
+ Wlc_PrsForEachLine( p, pTemp, i )
+ {
+ int k;
+ if ( !Wlc_PrsStrCmp( pTemp, "module" ) )
+ continue;
+ printf( "%3d : ", i );
+ for ( k = 0; k < 40; k++ )
+ printf( "%c", pTemp[k] ? pTemp[k] : ' ' );
+ printf( "\n" );
+ }
+*/
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline char * Wlc_PrsFindRange( char * pStr, int * End, int * Beg )
+{
+ *End = *Beg = 0;
+ pStr = Wlc_PrsSkipSpaces( pStr );
+ if ( pStr[0] != '[' )
+ return pStr;
+ pStr = Wlc_PrsSkipSpaces( pStr+1 );
+ if ( !Wlc_PrsIsDigit(pStr) )
+ return NULL;
+ *End = *Beg = atoi( pStr );
+ if ( Wlc_PrsFindSymbol( pStr, ':' ) == NULL )
+ {
+ pStr = Wlc_PrsFindSymbol( pStr, ']' );
+ if ( pStr == NULL )
+ return NULL;
+ }
+ else
+ {
+ pStr = Wlc_PrsFindSymbol( pStr, ':' );
+ pStr = Wlc_PrsSkipSpaces( pStr+1 );
+ if ( !Wlc_PrsIsDigit(pStr) )
+ return NULL;
+ *Beg = atoi( pStr );
+ pStr = Wlc_PrsFindSymbol( pStr, ']' );
+ if ( pStr == NULL )
+ return NULL;
+ }
+ assert( *End >= *Beg );
+ return pStr + 1;
+}
+static inline char * Wlc_PrsFindWord( char * pStr, char * pWord, int * fFound )
+{
+ *fFound = 0;
+ pStr = Wlc_PrsSkipSpaces( pStr );
+ if ( !Wlc_PrsStrCmp(pStr, pWord) )
+ return pStr;
+ *fFound = 1;
+ return pStr + strlen(pWord);
+}
+static inline char * Wlc_PrsFindName( char * pStr, char ** ppPlace )
+{
+ static char Buffer[WLV_PRS_MAX_LINE];
+ char * pThis = *ppPlace = Buffer;
+ pStr = Wlc_PrsSkipSpaces( pStr );
+ if ( !Wlc_PrsIsChar(pStr) )
+ return NULL;
+ while ( Wlc_PrsIsChar(pStr) )
+ *pThis++ = *pStr++;
+ *pThis = 0;
+ return pStr;
+}
+static inline char * Wlc_PrsReadName( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins )
+{
+ char * pName;
+ int NameId, fFound;
+ pStr = Wlc_PrsFindName( pStr, &pName );
+ if ( pStr == NULL )
+ return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name." );
+ NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
+ if ( !fFound )
+ return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is used but not declared.", pName );
+ Vec_IntPush( vFanins, NameId );
+ return Wlc_PrsSkipSpaces( pStr );
+}
+static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins )
+{
+ char * pName;
+ int Type = WLC_OBJ_NONE;
+ Vec_IntClear( vFanins );
+ pStr = Wlc_PrsSkipSpaces( pStr );
+ if ( pStr[0] != '=' )
+ return 0;
+ pStr = Wlc_PrsSkipSpaces( pStr+1 );
+ if ( pStr[0] == '(' )
+ {
+ char * pClose = Wlc_PrsFindClosingParanthesis( pStr, '(', ')' );
+ if ( pClose == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting closing paranthesis." );
+ *pStr = *pClose = ' ';
+ pStr = Wlc_PrsSkipSpaces( pStr );
+ }
+ if ( Wlc_PrsIsDigit(pStr) )
+ {
+ int nDigits, nBits = atoi( pStr );
+ pStr = Wlc_PrsFindSymbol( pStr, '\'' );
+ if ( pStr == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting constant symbol (\')." );
+ if ( pStr[1] == 's' )
+ pStr++;
+ if ( pStr[1] != 'h' )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting hexadecimal constant and not \"%c\".", pStr[1] );
+ Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
+ nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 );
+ if ( nDigits != (nBits + 3)/4 )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "The length of contant does not match." );
+ pStr += nDigits + 2;
+ Type = WLC_OBJ_CONST;
+ }
+ else if ( pStr[0] == '!' || pStr[0] == '~' )
+ {
+ if ( pStr[0] == '!' )
+ Type = WLC_OBJ_LOGIC_NOT;
+ else if ( pStr[0] == '~' )
+ Type = WLC_OBJ_BIT_NOT;
+ else assert( 0 );
+ if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name after !." );
+ }
+ else if ( pStr[0] == '&' || pStr[0] == '|' || pStr[0] == '^' )
+ {
+ if ( pStr[0] == '&' )
+ Type = WLC_OBJ_REDUCT_AND;
+ else if ( pStr[0] == '|' )
+ Type = WLC_OBJ_REDUCT_OR;
+ else if ( pStr[0] == '^' )
+ Type = WLC_OBJ_REDUCT_XOR;
+ else assert( 0 );
+ if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name after reduction operator." );
+ }
+ else if ( pStr[0] == '{' )
+ {
+ // THIS IS SHORTCUT TO DETECT zero padding AND sign extension
+ if ( Wlc_PrsFindSymbol(pStr+1, '{') )
+ {
+ if ( Wlc_PrsFindSymbol(pStr+1, '\'') )
+ Type = WLC_OBJ_BIT_ZEROPAD;
+ else
+ Type = WLC_OBJ_BIT_SIGNEXT;
+ pStr = Wlc_PrsFindSymbol(pStr+1, ',');
+ if ( pStr == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting one comma in this line." );
+ if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in sign-extension." );
+ pStr = Wlc_PrsSkipSpaces( pStr );
+ if ( pStr[0] != '}' )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "There is no closing brace (})." );
+ }
+ else // concatenation
+ {
+ while ( 1 )
+ {
+ if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in concatenation." );
+ if ( pStr[0] == '}' )
+ break;
+ if ( pStr[0] != ',' )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Expected comma (,) in this place." );
+ }
+ Type = WLC_OBJ_BIT_CONCAT;
+ }
+ assert( pStr[0] == '}' );
+ pStr++;
+ }
+ else
+ {
+ if ( !(pStr = Wlc_PrsReadName(p, pStr, vFanins)) )
+ return 0;
+ // get the next symbol
+ if ( pStr[0] == 0 )
+ Type = WLC_OBJ_BUF;
+ else if ( pStr[0] == '?' )
+ {
+ if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in MUX." );
+ if ( pStr[0] != ':' )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "MUX lacks the colon symbol (:)." );
+ if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in MUX." );
+ Type = WLC_OBJ_MUX;
+ }
+ else if ( pStr[0] == '[' )
+ {
+ int End, Beg;
+ pStr = Wlc_PrsFindRange( pStr, &End, &Beg );
+ Vec_IntPush( vFanins, (End << 16) | Beg );
+ Type = WLC_OBJ_BIT_SELECT;
+ }
+ else
+ {
+ if ( pStr[0] == '>' && pStr[1] == '>' && pStr[2] != '>' ) pStr += 2, Type = WLC_OBJ_SHIFT_R;
+ else if ( pStr[0] == '>' && pStr[1] == '>' && pStr[2] == '>' ) pStr += 3, Type = WLC_OBJ_SHIFT_RA;
+ else if ( pStr[0] == '<' && pStr[1] == '<' && pStr[2] != '<' ) pStr += 2, Type = WLC_OBJ_SHIFT_L;
+ else if ( pStr[0] == '<' && pStr[1] == '<' && pStr[2] == '<' ) pStr += 3, Type = WLC_OBJ_SHIFT_LA;
+ else if ( pStr[0] == '&' && pStr[1] != '&' ) pStr += 1, Type = WLC_OBJ_BIT_AND;
+ else if ( pStr[0] == '|' && pStr[1] != '|' ) pStr += 1, Type = WLC_OBJ_BIT_OR;
+ else if ( pStr[0] == '^' && pStr[1] != '^' ) pStr += 1, Type = WLC_OBJ_BIT_XOR;
+ else if ( pStr[0] == '&' && pStr[1] == '&' ) pStr += 2, Type = WLC_OBJ_LOGIC_AND;
+ else if ( pStr[0] == '|' && pStr[1] == '|' ) pStr += 2, Type = WLC_OBJ_LOGIC_OR;
+ else if ( pStr[0] == '=' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_EQU;
+ else if ( pStr[0] == '!' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_NOT;
+ else if ( pStr[0] == '<' && pStr[1] != '=' ) pStr += 1, Type = WLC_OBJ_COMP_LESS;
+ else if ( pStr[0] == '>' && pStr[1] != '=' ) pStr += 1, Type = WLC_OBJ_COMP_MORE;
+ else if ( pStr[0] == '<' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_LESSEQU;
+ else if ( pStr[0] == '>' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_MOREEQU;
+ else if ( pStr[0] == '+' ) pStr += 1, Type = WLC_OBJ_ARI_ADD;
+ else if ( pStr[0] == '-' ) pStr += 1, Type = WLC_OBJ_ARI_SUB;
+ else if ( pStr[0] == '*' && pStr[1] != '*' ) pStr += 1, Type = WLC_OBJ_ARI_MULTI;
+ else if ( pStr[0] == '/' ) pStr += 1, Type = WLC_OBJ_ARI_DIVIDE;
+ else if ( pStr[0] == '%' ) pStr += 1, Type = WLC_OBJ_ARI_MODULUS;
+ else if ( pStr[0] == '*' && pStr[1] == '*' ) pStr += 2, Type = WLC_OBJ_ARI_POWER;
+ else return Wlc_PrsWriteErrorMessage( p, pStr, "Unsupported operation (%c).", pStr[0] );
+ if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
+ return 0;
+ }
+ }
+ // make sure there is nothing left there
+ if ( pStr )
+ {
+ pStr = Wlc_PrsFindName( pStr, &pName );
+ if ( pStr != NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is left at the end of the line.", pName );
+ }
+ return Type;
+}
+int Wlc_PrsDerive( Wlc_Prs_t * p )
+{
+ char * pStart, * pName;
+ int i;
+ // go through the directives
+ Wlc_PrsForEachLine( p, pStart, i )
+ {
+ if ( Wlc_PrsStrCmp( pStart, "module" ) )
+ {
+ // get module name
+ pName = strtok( pStart + strlen("module"), " (" );
+ if ( pName == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read model name." );
+ if ( p->pNtk != NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Network is already defined." );
+ p->pNtk = Wlc_NtkAlloc( pName, Vec_IntSize(p->vStarts) );
+ p->pNtk->pManName = Abc_NamStart( Vec_IntSize(p->vStarts), 20 );
+ }
+ else if ( Wlc_PrsStrCmp( pStart, "endmodule" ) )
+ {
+ Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(p->pNtk) );
+ Vec_IntAppend( &p->pNtk->vNameIds, vTemp );
+ Vec_IntFree( vTemp );
+ break;
+ }
+ // these are read as part of the interface
+ else if ( Wlc_PrsStrCmp( pStart, "input" ) || Wlc_PrsStrCmp( pStart, "output" ) || Wlc_PrsStrCmp( pStart, "wire" ) )
+ {
+ int fFound = 0, Type = WLC_OBJ_NONE, iObj;
+ int Signed = 0, Beg = 0, End = 0, NameId;
+ if ( Wlc_PrsStrCmp( pStart, "input" ) )
+ Type = WLC_OBJ_PI, pStart += strlen("input");
+ else if ( Wlc_PrsStrCmp( pStart, "output" ) )
+ Type = WLC_OBJ_PO, pStart += strlen("output");
+ pStart = Wlc_PrsSkipSpaces( pStart );
+ if ( Wlc_PrsStrCmp( pStart, "wire" ) )
+ pStart += strlen("wire");
+ // read 'signed'
+ pStart = Wlc_PrsFindWord( pStart, "signed", &Signed );
+ // read range
+ pStart = Wlc_PrsFindRange( pStart, &End, &Beg );
+ if ( pStart == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read range." );
+ while ( 1 )
+ {
+ // read name
+ pStart = Wlc_PrsFindName( pStart, &pName );
+ if ( pStart == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name." );
+ NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
+ if ( fFound )
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is declared more than once.", pName );
+ iObj = Wlc_ObjAlloc( p->pNtk, Type, Signed, End, Beg );
+ assert( iObj == NameId );
+ // check next definition
+ pStart = Wlc_PrsSkipSpaces( pStart );
+ if ( pStart[0] == ',' )
+ {
+ pStart++;
+ continue;
+ }
+ // check definition
+ Type = Wlc_PrsFindDefinition( p, pStart, p->vFanins );
+ if ( Type )
+ {
+ Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, iObj );
+ Wlc_ObjUpdateType( p->pNtk, pObj, Type );
+ Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
+ }
+ break;
+ }
+ }
+ else if ( Wlc_PrsStrCmp( pStart, "assign" ) )
+ {
+ int Type, NameId, fFound;
+ pStart += strlen("assign");
+ // read name
+ pStart = Wlc_PrsFindName( pStart, &pName );
+ if ( pStart == NULL )
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after assign." );
+ NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
+ if ( !fFound )
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
+ // read definition
+ Type = Wlc_PrsFindDefinition( p, pStart, p->vFanins );
+ if ( Type )
+ {
+ Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, NameId );
+ Wlc_ObjUpdateType( p->pNtk, pObj, Type );
+ Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
+ }
+ else
+ return 0;
+ }
+// else if ( Wlc_PrsStrCmp( pStart, "CPL_FF" ) )
+ else
+ {
+ pStart = Wlc_PrsFindName( pStart, &pName );
+ return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line beginning with %s.", pName );
+ }
+ }
+ return 1;
+}
+Wlc_Ntk_t * Wlc_ReadVer( char * pFileName )
+{
+ Wlc_Prs_t * p;
+ Wlc_Ntk_t * pNtk = NULL;
+ // start the parser
+ p = Wlc_PrsStart( pFileName );
+ if ( p == NULL )
+ return NULL;
+ // detect lines
+ if ( !Wlc_PrsPrepare( p ) )
+ goto finish;
+ // parse models
+ if ( !Wlc_PrsDerive( p ) )
+ goto finish;
+ // derive topological order
+ pNtk = Wlc_NtkDupDfs( p->pNtk );
+ Wlc_NtkTransferNames( pNtk, p->pNtk );
+finish:
+ Wlc_PrsPrintErrorMessage( p );
+ Wlc_PrsStop( p );
+ return pNtk;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Io_ReadWordTest( char * pFileName )
+{
+ Gia_Man_t * pNew;
+ Wlc_Ntk_t * pNtk = Wlc_ReadVer( pFileName );
+ if ( pNtk == NULL )
+ return;
+ Wlc_WriteVer( pNtk, "test.v" );
+
+ pNew = Wlc_NtkBitBlast( pNtk );
+ Gia_AigerWrite( pNew, "test.aig", 0, 0 );
+ Gia_ManStop( pNew );
+
+ Wlc_NtkFree( pNtk );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+