/**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