diff options
Diffstat (limited to 'src/base/wlc/wlcReadVer.c')
-rw-r--r-- | src/base/wlc/wlcReadVer.c | 711 |
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 + |