Commit ec0b9b6b by Alan Mishchenko

Improvements to word-level Verilog parser.

parent 6d0b555d
......@@ -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; }
......
......@@ -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) );
......
......@@ -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;
}
////////////////////////////////////////////////////////////////////////
......
......@@ -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
{
......
......@@ -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 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment