mirror of https://github.com/YosysHQ/abc.git
Improvements to word-level Verilog parser.
This commit is contained in:
parent
6d0b555dab
commit
ec0b9b6b6e
|
|
@ -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 )
|
||||
|
|
|
|||
Loading…
Reference in New Issue