diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2014-09-16 22:08:22 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2014-09-16 22:08:22 -0700 |
commit | ec0b9b6b6ed44181aa938dfb581648cf34f4bd28 (patch) | |
tree | a3b4d0cdd14a1ff8fcd97ea796956a434e1f3eee /src/base | |
parent | 6d0b555dabe44d5b6eb428e05fea673395602b65 (diff) | |
download | abc-ec0b9b6b6ed44181aa938dfb581648cf34f4bd28.tar.gz abc-ec0b9b6b6ed44181aa938dfb581648cf34f4bd28.tar.bz2 abc-ec0b9b6b6ed44181aa938dfb581648cf34f4bd28.zip |
Improvements to word-level Verilog parser.
Diffstat (limited to 'src/base')
-rw-r--r-- | src/base/wlc/wlc.h | 6 | ||||
-rw-r--r-- | src/base/wlc/wlcBlast.c | 6 | ||||
-rw-r--r-- | src/base/wlc/wlcNtk.c | 15 | ||||
-rw-r--r-- | src/base/wlc/wlcReadVer.c | 327 | ||||
-rw-r--r-- | src/base/wlc/wlcWriteVer.c | 1 |
5 files changed, 277 insertions, 78 deletions
diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 1cb74848..75fa11dd 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -80,7 +80,8 @@ typedef enum { WLC_OBJ_ARI_DIVIDE, // 36: arithmetic division WLC_OBJ_ARI_MODULUS, // 37: arithmetic modulus WLC_OBJ_ARI_POWER, // 38: arithmetic power - WLC_OBJ_NUMBER // 39: unused + WLC_OBJ_TABLE, // 39: arithmetic power + WLC_OBJ_NUMBER // 40: unused } Wlc_ObjType_t; @@ -117,6 +118,8 @@ struct Wlc_Ntk_t_ int iObj; int nObjsAlloc; Mem_Flex_t * pMemFanin; + Mem_Flex_t * pMemTable; + Vec_Ptr_t * vTables; // object names Abc_Nam_t * pManName; // object names Vec_Int_t vNameIds; // object name IDs @@ -159,6 +162,7 @@ static inline int Wlc_ObjRange( Wlc_Obj_t * p ) static inline int Wlc_ObjRangeEnd( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->Fanins[1] >> 16; } static inline int Wlc_ObjRangeBeg( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_BIT_SELECT); return p->Fanins[1] & 0xFFFF; } static inline int * Wlc_ObjConstValue( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_CONST); return Wlc_ObjFanins(p); } +static inline int Wlc_ObjTableId( Wlc_Obj_t * p ) { assert(p->Type == WLC_OBJ_TABLE); return p->Fanins[1]; } static inline void Wlc_NtkCleanCopy( Wlc_Ntk_t * p ) { Vec_IntFill( &p->vCopies, p->nObjsAlloc, 0 ); } static inline int Wlc_NtkHasCopy( Wlc_Ntk_t * p ) { return Vec_IntSize( &p->vCopies ) > 0; } diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 54200956..eb45773d 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -328,6 +328,12 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p ) assert( Vec_IntSize(vTemp3) == nRange ); Vec_IntAppend( vBits, vTemp3 ); } + else if ( pObj->Type == WLC_OBJ_TABLE ) + { + assert( pObj->Type != WLC_OBJ_TABLE ); + for ( k = 0; k < nRange; k++ ) + Vec_IntPush( vBits, 0 ); + } else assert( 0 ); } assert( nBits == Vec_IntSize(vBits) ); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index ac8f2e48..2ca90d00 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -68,7 +68,8 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { "//", // 36: arithmetic division "%%", // 37: arithmetic modulus "**", // 38: arithmetic power - NULL // 39: unused + "table", // 39: lookup table + NULL // 40: unused }; //////////////////////////////////////////////////////////////////////// @@ -155,10 +156,10 @@ void Wlc_ObjAddFanins( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Int_t * vFanins ) if ( Wlc_ObjHasArray(pObj) ) pObj->pFanins[0] = (int *)Mem_FlexEntryFetch( p->pMemFanin, Vec_IntSize(vFanins) * sizeof(int) ); memcpy( Wlc_ObjFanins(pObj), Vec_IntArray(vFanins), sizeof(int) * Vec_IntSize(vFanins) ); - // special treatment of CONST and SELECT + // special treatment of CONST, SELECT and TABLE if ( pObj->Type == WLC_OBJ_CONST ) pObj->nFanins = 0; - else if ( pObj->Type == WLC_OBJ_BIT_SELECT ) + else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE ) pObj->nFanins = 1; } void Wlc_NtkFree( Wlc_Ntk_t * p ) @@ -167,6 +168,9 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) Abc_NamStop( p->pManName ); if ( p->pMemFanin ) Mem_FlexStop( p->pMemFanin, 0 ); + if ( p->pMemTable ) + Mem_FlexStop( p->pMemTable, 0 ); + Vec_PtrFreeP( &p->vTables ); ABC_FREE( p->vPis.pArray ); ABC_FREE( p->vPos.pArray ); ABC_FREE( p->vCis.pArray ); @@ -258,7 +262,7 @@ void Wlc_ObjCollectCopyFanins( Wlc_Ntk_t * p, int iObj, Vec_Int_t * vFanins ) for ( i = 0; i < nInts; i++ ) Vec_IntPush( vFanins, pInts[i] ); } - else if ( pObj->Type == WLC_OBJ_BIT_SELECT ) + else if ( pObj->Type == WLC_OBJ_BIT_SELECT || pObj->Type == WLC_OBJ_TABLE ) { assert( Vec_IntSize(vFanins) == 1 ); Vec_IntPush( vFanins, pObj->Fanins[1] ); @@ -316,6 +320,9 @@ void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ) pNew->pManName = p->pManName; p->pManName = NULL; Vec_IntErase( &p->vNameIds ); + // transfer table + pNew->pMemTable = p->pMemTable; p->pMemTable = NULL; + pNew->vTables = p->vTables; p->vTables = NULL; } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index cf880cd5..724699b7 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -40,6 +40,9 @@ struct Wlc_Prs_t_ Vec_Int_t * vStarts; Vec_Int_t * vFanins; Wlc_Ntk_t * pNtk; + Mem_Flex_t * pMemTable; + Vec_Ptr_t * vTables; + int nConsts; char sError[WLV_PRS_MAX_LINE]; }; @@ -47,8 +50,10 @@ static inline int Wlc_PrsOffset( Wlc_Prs_t * p, char * pStr ) { return 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 ) \ +#define Wlc_PrsForEachLine( p, pLine, i ) \ for ( i = 0; (i < Vec_IntSize((p)->vStarts)) && ((pLine) = Wlc_PrsStr(p, Vec_IntEntry((p)->vStarts, i))); i++ ) +#define Wlc_PrsForEachLineStart( p, pLine, i, Start ) \ + for ( i = Start; (i < Vec_IntSize((p)->vStarts)) && ((pLine) = Wlc_PrsStr(p, Vec_IntEntry((p)->vStarts, i))); i++ ) //////////////////////////////////////////////////////////////////////// @@ -79,12 +84,17 @@ Wlc_Prs_t * Wlc_PrsStart( char * pFileName ) p->vLines = Vec_IntAlloc( p->nFileSize / 50 ); p->vStarts = Vec_IntAlloc( p->nFileSize / 50 ); p->vFanins = Vec_IntAlloc( 100 ); + p->vTables = Vec_PtrAlloc( 1000 ); + p->pMemTable = Mem_FlexStart(); return p; } void Wlc_PrsStop( Wlc_Prs_t * p ) { if ( p->pNtk ) Wlc_NtkFree( p->pNtk ); + if ( p->pMemTable ) + Mem_FlexStop( p->pMemTable, 0 ); + Vec_PtrFreeP( &p->vTables ); Vec_IntFree( p->vLines ); Vec_IntFree( p->vStarts ); Vec_IntFree( p->vFanins ); @@ -386,16 +396,78 @@ static inline char * Wlc_PrsFindName( char * pStr, char ** ppPlace ) *pThis = 0; return pStr; } +static inline char * Wlc_PrsReadConstant( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins, int * pRange, int * pSigned ) +{ + int nDigits, nBits = atoi( pStr ); + *pRange = -1; + *pSigned = 0; + pStr = Wlc_PrsSkipSpaces( pStr ); + if ( Wlc_PrsFindSymbol( pStr, '\'' ) == NULL ) + { + // handle decimal number + int Number = atoi( pStr ); + *pRange = Abc_Base2Log( Number ); + while ( Wlc_PrsIsDigit(pStr) ) + pStr++; + return pStr; + } + pStr = Wlc_PrsFindSymbol( pStr, '\'' ); + if ( pStr[1] == 's' ) + { + *pSigned = 1; + pStr++; + } + if ( pStr[1] != 'h' ) + return (char *)(ABC_PTRINT_T)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 (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "The length of a constant does not match." ); + printf( "Warning: The length of a constant (%d hex digits) does not match the number of bits (%d).\n", nDigits, nBits ); + } + *pRange = nBits; + pStr += 2; + while ( Wlc_PrsIsChar(pStr) ) + pStr++; + 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 ); + int NameId, fFound, iObj; + pStr = Wlc_PrsSkipSpaces( pStr ); + if ( Wlc_PrsIsDigit(pStr) ) + { + char Buffer[100]; + int Range, Signed; + Vec_Int_t * vFanins = Vec_IntAlloc(0); + pStr = Wlc_PrsReadConstant( p, pStr, vFanins, &Range, &Signed ); + if ( pStr == NULL ) + { + Vec_IntFree( vFanins ); + return 0; + } + // create new node + iObj = Wlc_ObjAlloc( p->pNtk, WLC_OBJ_CONST, Signed, Range-1, 0 ); + Wlc_ObjAddFanins( p->pNtk, Wlc_NtkObj(p->pNtk, iObj), vFanins ); + Vec_IntFree( vFanins ); + // add node's name + sprintf( Buffer, "const%d", p->nConsts++ ); + NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, Buffer, &fFound ); + if ( fFound ) + return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is already used.", Buffer ); + assert( iObj == NameId ); + } + else + { + char * pName; + 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 ); } @@ -403,6 +475,7 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * { char * pName; int Type = WLC_OBJ_NONE; + int fRotating = 0; Vec_IntClear( vFanins ); pStr = Wlc_PrsSkipSpaces( pStr ); if ( pStr[0] != '=' ) @@ -410,27 +483,32 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * 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 ); + // consider rotating shifter + if ( Wlc_PrsFindSymbolTwo(pStr, '>', '>') && Wlc_PrsFindSymbolTwo(pStr, '<', '<') ) + { + // THIS IS A HACK TO DETECT rotating shifters + char * pClose = Wlc_PrsFindClosingParanthesis( pStr, '(', ')' ); + if ( pClose == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting closing paranthesis." ); + *pStr = ' '; *pClose = 0; + pStr = Wlc_PrsSkipSpaces( pStr ); + fRotating = 1; + } + else + { + 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, '\'' ); + int Range, Signed; + pStr = Wlc_PrsReadConstant( p, pStr, vFanins, &Range, &Signed ); 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; + return 0; Type = WLC_OBJ_CONST; } else if ( pStr[0] == '!' || pStr[0] == '~' ) @@ -440,7 +518,16 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * else if ( pStr[0] == '~' ) Type = WLC_OBJ_BIT_NOT; else assert( 0 ); - if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + // skip parantheses + 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 = ' '; + } + if ( !(pStr = Wlc_PrsReadName(p, pStr, vFanins)) ) return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name after !." ); } else if ( pStr[0] == '&' || pStr[0] == '|' || pStr[0] == '^' ) @@ -457,7 +544,7 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * } else if ( pStr[0] == '{' ) { - // THIS IS SHORTCUT TO DETECT zero padding AND sign extension + // THIS IS A HACK TO DETECT zero padding AND sign extension if ( Wlc_PrsFindSymbol(pStr+1, '{') ) { if ( Wlc_PrsFindSymbol(pStr+1, '\'') ) @@ -477,7 +564,8 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * { while ( 1 ) { - if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) ) + pStr = Wlc_PrsSkipSpaces( pStr+1 ); + if ( !(pStr = Wlc_PrsReadName(p, pStr, vFanins)) ) return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in concatenation." ); if ( pStr[0] == '}' ) break; @@ -550,6 +638,54 @@ static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * } return Type; } +int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart ) +{ + 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 ) + { + char * pName; + // 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; + } + return 1; +} int Wlc_PrsDerive( Wlc_Prs_t * p ) { char * pStart, * pName; @@ -560,13 +696,63 @@ int Wlc_PrsDerive( Wlc_Prs_t * p ) if ( Wlc_PrsStrCmp( pStart, "module" ) ) { // get module name - pName = strtok( pStart + strlen("module"), " (" ); + pName = strtok( pStart + strlen("module"), " \r\n\t(,)" ); if ( pName == NULL ) return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read model name." ); + if ( Wlc_PrsStrCmp( pName, "table" ) ) + { + // THIS IS A HACK TO DETECT tables + int v, b, Value, nBits, nInts, * pTable; + Vec_Int_t * vValues = Vec_IntAlloc( 256 ); + Wlc_PrsForEachLineStart( p, pStart, i, i+1 ) + { + if ( Wlc_PrsStrCmp( pStart, "endcase" ) ) + break; + pStart = Wlc_PrsFindSymbol( pStart, '\'' ); + if ( pStart == NULL ) + continue; + pStart = Wlc_PrsFindSymbol( pStart+2, '\'' ); + if ( pStart == NULL ) + continue; + Value = 0; + Abc_TtReadHexNumber( (word *)&Value, pStart+2 ); + Vec_IntPush( vValues, Value ); + } + //Vec_IntPrint( vValues ); + nBits = Abc_Base2Log( Vec_IntSize(vValues) ); + if ( Vec_IntSize(vValues) != (1 << nBits) ) + { + Vec_IntFree( vValues ); + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read module \"%s\".", pName ); + } + // create bitmap + nInts = Abc_BitWordNum( nBits * Vec_IntSize(vValues) ); + pTable = (unsigned *)Mem_FlexEntryFetch( p->pMemTable, nInts * sizeof(unsigned) ); + memset( pTable, 0, nInts * sizeof(unsigned) ); + Vec_IntForEachEntry( vValues, Value, v ) + for ( b = 0; b < nBits; b++ ) + if ( (Value >> b) & 1 ) + Abc_InfoSetBit( pTable, v * nBits + b ); + Vec_PtrPush( p->vTables, pTable ); + Vec_IntFree( vValues ); + continue; + } 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 ); + p->pNtk->pMemTable = p->pMemTable; p->pMemTable = NULL; + p->pNtk->vTables = p->vTables; p->vTables = NULL; + // read the argument definitions + while ( (pName = strtok( NULL, "(,)" )) ) + { + pName = Wlc_PrsSkipSpaces( pName ); + if ( Wlc_PrsStrCmp( pName, "input" ) || Wlc_PrsStrCmp( pName, "output" ) || Wlc_PrsStrCmp( pName, "wire" ) ) + { + if ( !Wlc_PrsReadDeclaration( p, pName ) ) + return 0; + } + } } else if ( Wlc_PrsStrCmp( pStart, "endmodule" ) ) { @@ -578,49 +764,8 @@ int Wlc_PrsDerive( Wlc_Prs_t * p ) // 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; - } + if ( !Wlc_PrsReadDeclaration( p, pStart ) ) + return 0; } else if ( Wlc_PrsStrCmp( pStart, "assign" ) ) { @@ -644,6 +789,42 @@ int Wlc_PrsDerive( Wlc_Prs_t * p ) else return 0; } + else if ( Wlc_PrsStrCmp( pStart, "table" ) ) + { + // THIS IS A HACK TO DETECT tables + int NameId, fFound, iTable = atoi( pStart + strlen("table") ); + // find opening + pStart = Wlc_PrsFindSymbol( pStart, '(' ); + if ( pStart == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." ); + // read input + pStart = Wlc_PrsFindName( pStart+1, &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 ); + // save inputs + Vec_IntClear( p->vFanins ); + Vec_IntPush( p->vFanins, NameId ); + Vec_IntPush( p->vFanins, iTable ); + // find comma + pStart = Wlc_PrsFindSymbol( pStart, ',' ); + if ( pStart == NULL ) + return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." ); + // read output + pStart = Wlc_PrsFindName( pStart+1, &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 ); + { + Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, NameId ); + Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_TABLE ); + Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); + } + } // else if ( Wlc_PrsStrCmp( pStart, "CPL_FF" ) ) else { diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index f7a218e1..3086011a 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -87,6 +87,7 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p ) int nDigits = Abc_Base10Log(pObj->End+1) + Abc_Base10Log(pObj->Beg+1); sprintf( Range, "%s[%d:%d]%*s", pObj->Signed ? "signed ":" ", pObj->End, pObj->Beg, 8-nDigits, "" ); fprintf( pFile, " " ); + assert( pObj->Type != WLC_OBJ_TABLE ); if ( pObj->Type == WLC_OBJ_PI ) fprintf( pFile, "input wire %s %-16s", Range, pName ); else if ( pObj->Type == WLC_OBJ_PO ) |