2014-09-12 22:40:48 +02:00
/**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
2017-01-27 06:43:28 +01:00
# define WLV_PRS_MAX_LINE 10000
2014-09-12 22:40:48 +02:00
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 ;
2014-09-17 07:08:22 +02:00
Mem_Flex_t * pMemTable ;
Vec_Ptr_t * vTables ;
2018-04-16 06:23:22 +02:00
Vec_Str_t * vPoPairs ;
2014-09-17 07:08:22 +02:00
int nConsts ;
2016-04-05 03:09:41 +02:00
int nNonZero [ 4 ] ;
int nNegative [ 4 ] ;
int nReverse [ 4 ] ;
2014-09-12 22:40:48 +02:00
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 ) ) ; }
2014-09-17 07:08:22 +02:00
# define Wlc_PrsForEachLine( p, pLine, i ) \
2014-09-12 22:40:48 +02:00
for ( i = 0 ; ( i < Vec_IntSize ( ( p ) - > vStarts ) ) & & ( ( pLine ) = Wlc_PrsStr ( p , Vec_IntEntry ( ( p ) - > vStarts , i ) ) ) ; i + + )
2014-09-17 07:08:22 +02:00
# 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 + + )
2014-09-12 22:40:48 +02:00
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [ ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-10-07 07:04:11 +02:00
Wlc_Prs_t * Wlc_PrsStart ( char * pFileName , char * pStr )
2014-09-12 22:40:48 +02:00
{
Wlc_Prs_t * p ;
2016-10-07 07:04:11 +02:00
if ( pFileName & & ! Extra_FileCheck ( pFileName ) )
2014-09-12 22:40:48 +02:00
return NULL ;
p = ABC_CALLOC ( Wlc_Prs_t , 1 ) ;
p - > pFileName = pFileName ;
2016-10-07 07:04:11 +02:00
p - > pBuffer = pStr ? Abc_UtilStrsav ( pStr ) : Extra_FileReadContents ( pFileName ) ;
2014-09-12 22:40:48 +02:00
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 ) ;
2014-09-17 07:08:22 +02:00
p - > vTables = Vec_PtrAlloc ( 1000 ) ;
p - > pMemTable = Mem_FlexStart ( ) ;
2014-09-12 22:40:48 +02:00
return p ;
}
void Wlc_PrsStop ( Wlc_Prs_t * p )
{
if ( p - > pNtk )
Wlc_NtkFree ( p - > pNtk ) ;
2014-09-17 07:08:22 +02:00
if ( p - > pMemTable )
Mem_FlexStop ( p - > pMemTable , 0 ) ;
2018-04-16 06:23:22 +02:00
Vec_StrFreeP ( & p - > vPoPairs ) ;
2014-09-17 07:08:22 +02:00
Vec_PtrFreeP ( & p - > vTables ) ;
2014-09-12 22:40:48 +02:00
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 [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2015-06-24 00:53:41 +02:00
int Wlc_PrsFindLine ( Wlc_Prs_t * p , char * pCur )
{
int Entry , iLine = 0 ;
Vec_IntForEachEntry ( p - > vLines , Entry , iLine )
if ( Entry > pCur - p - > pBuffer )
return iLine + 1 ;
return - 1 ;
}
2014-09-12 22:40:48 +02:00
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
{
2015-06-24 00:53:41 +02:00
int iLine = Wlc_PrsFindLine ( p , pCur ) ;
sprintf ( p - > sError , " %s (line %d): %s \n " , p - > pFileName , iLine , pMessage ) ;
2014-09-12 22:40:48 +02:00
}
2014-09-18 20:46:14 +02:00
ABC_FREE ( pMessage ) ;
2014-09-12 22:40:48 +02:00
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 ' ) | |
2014-10-11 04:17:19 +02:00
pStr [ 0 ] = = ' _ ' | | pStr [ 0 ] = = ' $ ' | | pStr [ 0 ] = = ' \\ ' ;
2014-09-12 22:40:48 +02:00
}
static inline char * Wlc_PrsSkipSpaces ( char * pStr )
{
while ( * pStr & & * pStr = = ' ' )
pStr + + ;
return pStr ;
}
static inline char * Wlc_PrsFindSymbol ( char * pStr , char Symb )
{
2014-10-11 04:17:19 +02:00
int fNotName = 1 ;
2014-09-12 22:40:48 +02:00
for ( ; * pStr ; pStr + + )
2014-10-11 04:17:19 +02:00
{
if ( fNotName & & * pStr = = Symb )
2014-09-12 22:40:48 +02:00
return pStr ;
2014-10-11 04:17:19 +02:00
if ( pStr [ 0 ] = = ' \\ ' )
fNotName = 0 ;
else if ( ! fNotName & & * pStr = = ' ' )
fNotName = 1 ;
}
2014-09-12 22:40:48 +02:00
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 ;
}
2015-02-08 07:29:14 +01:00
static inline char * Wlc_PrsFindClosingParenthesis ( char * pStr , char Open , char Close )
2014-09-12 22:40:48 +02:00
{
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 ] = ' ' ;
2018-04-16 06:23:22 +02:00
else if ( ! strncmp ( pCur + 3 , " Pair: " , 5 ) )
{
if ( p - > vPoPairs = = NULL )
p - > vPoPairs = Vec_StrAlloc ( 100 ) ;
for ( pNext = pCur + 9 ; * pNext ! = ' \n ' ; pNext + + )
{
if ( * pNext = = ' ' )
Vec_StrPush ( p - > vPoPairs , ' \0 ' ) ;
else if ( * pNext ! = ' \r ' )
Vec_StrPush ( p - > vPoPairs , * pNext ) ;
}
if ( Vec_StrEntryLast ( p - > vPoPairs ) ! = 0 )
Vec_StrPush ( p - > vPoPairs , 0 ) ;
}
2014-09-12 22:40:48 +02:00
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 ;
}
2014-10-11 04:17:19 +02:00
/**Function*************************************************************
Synopsis [ Modified version of strtok ( ) . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * Wlc_PrsStrtok ( char * s , const char * delim )
{
const char * spanp ;
int c , sc ;
char * tok ;
static char * last ;
if ( s = = NULL & & ( s = last ) = = NULL )
return NULL ;
// skip leading delimiters
cont :
c = * s + + ;
for ( spanp = delim ; ( sc = * spanp + + ) ! = 0 ; )
if ( c = = sc )
goto cont ;
if ( c = = 0 ) // no non-delimiter characters
return ( last = NULL ) ;
// tok = s - 1;
if ( c ! = ' \\ ' )
tok = s - 1 ;
else
tok = s - 1 ;
// go back to the first non-delimiter character
s - - ;
// find the token
for ( ; ; )
{
c = * s + + ;
if ( c = = ' \\ ' ) // skip blind characters
{
while ( c ! = ' ' )
c = * s + + ;
c = * s + + ;
}
spanp = delim ;
do {
if ( ( sc = * spanp + + ) = = c )
{
if ( c = = 0 )
s = NULL ;
else
s [ - 1 ] = 0 ;
last = s ;
return ( tok ) ;
}
} while ( sc ! = 0 ) ;
}
// not reached
return NULL ;
}
2015-01-22 02:43:46 +01:00
/**Function*************************************************************
Synopsis [ ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * Wlc_PrsConvertInitValues ( Wlc_Ntk_t * p )
{
Wlc_Obj_t * pObj ;
int i , k , Value , * pInits ;
char * pResult ;
Vec_Str_t * vStr = Vec_StrAlloc ( 1000 ) ;
2015-01-25 20:21:36 +01:00
Vec_IntForEachEntry ( p - > vInits , Value , i )
2015-01-22 02:43:46 +01:00
{
if ( Value < 0 )
{
for ( k = 0 ; k < - Value ; k + + )
Vec_StrPush ( vStr , ' 0 ' ) ;
continue ;
}
pObj = Wlc_NtkObj ( p , Value ) ;
2015-01-25 20:21:36 +01:00
Value = Wlc_ObjRange ( pObj ) ;
2015-01-23 00:16:45 +01:00
while ( pObj - > Type = = WLC_OBJ_BUF )
pObj = Wlc_NtkObj ( p , Wlc_ObjFaninId0 ( pObj ) ) ;
2016-02-03 00:43:19 +01:00
pInits = ( pObj - > Type = = WLC_OBJ_CONST & & ! pObj - > fXConst ) ? Wlc_ObjConstValue ( pObj ) : NULL ;
2015-01-25 20:21:36 +01:00
for ( k = 0 ; k < Abc_MinInt ( Value , Wlc_ObjRange ( pObj ) ) ; k + + )
2015-01-22 02:45:48 +01:00
Vec_StrPush ( vStr , ( char ) ( pInits ? ' 0 ' + Abc_InfoHasBit ( ( unsigned * ) pInits , k ) : ' X ' ) ) ;
2015-01-25 20:21:36 +01:00
// extend values with zero, in case the init value signal has different range compared to constant used
for ( ; k < Value ; k + + )
Vec_StrPush ( vStr , ' 0 ' ) ;
// update vInits to contain either number of values or PI index
2016-02-03 00:43:19 +01:00
Vec_IntWriteEntry ( p - > vInits , i , ( pInits | | pObj - > fXConst ) ? - Value : Wlc_ObjCiId ( pObj ) ) ;
2015-01-22 02:43:46 +01:00
}
Vec_StrPush ( vStr , ' \0 ' ) ;
pResult = Vec_StrReleaseArray ( vStr ) ;
Vec_StrFree ( vStr ) ;
return pResult ;
}
2014-09-12 22:40:48 +02:00
/**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 ) ;
2016-04-05 03:09:41 +02:00
if ( ! Wlc_PrsIsDigit ( pStr ) & & pStr [ 0 ] ! = ' - ' )
2014-09-12 22:40:48 +02:00
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 ) ;
2016-04-05 03:09:41 +02:00
if ( ! Wlc_PrsIsDigit ( pStr ) & & pStr [ 0 ] ! = ' - ' )
2014-09-12 22:40:48 +02:00
return NULL ;
* Beg = atoi ( pStr ) ;
pStr = Wlc_PrsFindSymbol ( pStr , ' ] ' ) ;
if ( pStr = = NULL )
return NULL ;
}
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 ;
2018-04-16 06:23:22 +02:00
int fNotName = 1 , Count = 0 ;
2014-09-12 22:40:48 +02:00
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
if ( ! Wlc_PrsIsChar ( pStr ) )
return NULL ;
2014-10-11 04:17:19 +02:00
// while ( Wlc_PrsIsChar(pStr) )
// *pThis++ = *pStr++;
while ( * pStr )
{
if ( fNotName & & ! Wlc_PrsIsChar ( pStr ) )
break ;
if ( * pStr = = ' \\ ' )
2018-04-16 06:23:22 +02:00
{
Count + + ;
2014-10-11 04:17:19 +02:00
fNotName = 0 ;
2018-04-16 06:23:22 +02:00
}
2014-10-11 04:17:19 +02:00
else if ( ! fNotName & & * pStr = = ' ' )
2018-04-16 06:23:22 +02:00
{
Count - - ;
if ( ! Count )
fNotName = 1 ;
}
2014-09-12 22:40:48 +02:00
* pThis + + = * pStr + + ;
2014-10-11 04:17:19 +02:00
}
2014-09-12 22:40:48 +02:00
* pThis = 0 ;
return pStr ;
}
2016-02-03 00:43:19 +01:00
static inline char * Wlc_PrsReadConstant ( Wlc_Prs_t * p , char * pStr , Vec_Int_t * vFanins , int * pRange , int * pSigned , int * pXValue )
2014-09-17 07:08:22 +02:00
{
2014-09-24 06:22:18 +02:00
int i , nDigits , nBits = atoi ( pStr ) ;
2014-09-17 07:08:22 +02:00
* pRange = - 1 ;
* pSigned = 0 ;
2016-02-03 00:43:19 +01:00
* pXValue = 0 ;
2014-09-17 07:08:22 +02:00
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
if ( Wlc_PrsFindSymbol ( pStr , ' \' ' ) = = NULL )
{
// handle decimal number
int Number = atoi ( pStr ) ;
2014-11-30 04:34:47 +01:00
* pRange = Abc_Base2Log ( Number + 1 ) ;
assert ( * pRange < 32 ) ;
2014-09-17 07:08:22 +02:00
while ( Wlc_PrsIsDigit ( pStr ) )
pStr + + ;
2014-09-18 00:14:17 +02:00
Vec_IntFill ( vFanins , 1 , Number ) ;
2014-09-17 07:08:22 +02:00
return pStr ;
}
pStr = Wlc_PrsFindSymbol ( pStr , ' \' ' ) ;
if ( pStr [ 1 ] = = ' s ' )
{
* pSigned = 1 ;
pStr + + ;
}
2014-09-24 06:22:18 +02:00
if ( pStr [ 1 ] = = ' b ' )
{
Vec_IntFill ( vFanins , Abc_BitWordNum ( nBits ) , 0 ) ;
for ( i = 0 ; i < nBits ; i + + )
if ( pStr [ 2 + i ] = = ' 1 ' )
2015-02-08 07:05:02 +01:00
Abc_InfoSetBit ( ( unsigned * ) Vec_IntArray ( vFanins ) , nBits - 1 - i ) ;
2014-09-24 06:22:18 +02:00
else if ( pStr [ 2 + i ] ! = ' 0 ' )
return ( char * ) ( ABC_PTRINT_T ) Wlc_PrsWriteErrorMessage ( p , pStr , " Wrong digit in binary constant \" %c \" . " , pStr [ 2 + i ] ) ;
* pRange = nBits ;
pStr + = 2 + nBits ;
return pStr ;
}
2014-09-17 07:08:22 +02:00
if ( pStr [ 1 ] ! = ' h ' )
return ( char * ) ( ABC_PTRINT_T ) Wlc_PrsWriteErrorMessage ( p , pStr , " Expecting hexadecimal constant and not \" %c \" . " , pStr [ 1 ] ) ;
2016-02-03 00:43:19 +01:00
* pXValue = ( pStr [ 2 ] = = ' x ' | | pStr [ 2 ] = = ' X ' ) ;
2014-09-17 07:08:22 +02:00
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." );
2014-09-18 00:14:17 +02:00
// printf( "Warning: The length of a constant (%d hex digits) does not match the number of bits (%d).\n", nDigits, nBits );
2014-09-17 07:08:22 +02:00
}
* pRange = nBits ;
pStr + = 2 ;
while ( Wlc_PrsIsChar ( pStr ) )
pStr + + ;
return pStr ;
}
2014-09-12 22:40:48 +02:00
static inline char * Wlc_PrsReadName ( Wlc_Prs_t * p , char * pStr , Vec_Int_t * vFanins )
{
2014-09-17 07:08:22 +02:00
int NameId , fFound , iObj ;
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
if ( Wlc_PrsIsDigit ( pStr ) )
{
char Buffer [ 100 ] ;
2016-02-03 00:43:19 +01:00
int Range , Signed , XValue = 0 ;
2014-09-17 07:08:22 +02:00
Vec_Int_t * vFanins = Vec_IntAlloc ( 0 ) ;
2016-02-03 00:43:19 +01:00
pStr = Wlc_PrsReadConstant ( p , pStr , vFanins , & Range , & Signed , & XValue ) ;
2014-09-17 07:08:22 +02:00
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 ) ;
2016-02-03 00:43:19 +01:00
Wlc_NtkObj ( p - > pNtk , iObj ) - > fXConst = XValue ;
2014-09-17 07:08:22 +02:00
Vec_IntFree ( vFanins ) ;
// add node's name
2014-09-18 00:14:17 +02:00
sprintf ( Buffer , " _c%d_ " , p - > nConsts + + ) ;
2014-09-17 07:08:22 +02:00
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 )
2014-10-11 04:17:19 +02:00
return ( char * ) ( ABC_PTRINT_T ) Wlc_PrsWriteErrorMessage ( p , pStr , " Cannot read name in assign-statement. " ) ;
2014-09-17 07:08:22 +02:00
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 ) ;
}
2014-09-12 22:40:48 +02:00
Vec_IntPush ( vFanins , NameId ) ;
return Wlc_PrsSkipSpaces ( pStr ) ;
}
2016-02-03 00:43:19 +01:00
static inline int Wlc_PrsFindDefinition ( Wlc_Prs_t * p , char * pStr , Vec_Int_t * vFanins , int * pXValue )
2014-09-12 22:40:48 +02:00
{
char * pName ;
int Type = WLC_OBJ_NONE ;
2014-09-17 07:08:22 +02:00
int fRotating = 0 ;
2014-09-12 22:40:48 +02:00
Vec_IntClear ( vFanins ) ;
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
if ( pStr [ 0 ] ! = ' = ' )
return 0 ;
pStr = Wlc_PrsSkipSpaces ( pStr + 1 ) ;
if ( pStr [ 0 ] = = ' ( ' )
{
2014-09-17 07:08:22 +02:00
// consider rotating shifter
if ( Wlc_PrsFindSymbolTwo ( pStr , ' > ' , ' > ' ) & & Wlc_PrsFindSymbolTwo ( pStr , ' < ' , ' < ' ) )
{
// THIS IS A HACK TO DETECT rotating shifters
2015-02-08 07:29:14 +01:00
char * pClose = Wlc_PrsFindClosingParenthesis ( pStr , ' ( ' , ' ) ' ) ;
2014-09-17 07:08:22 +02:00
if ( pClose = = NULL )
2015-02-08 07:29:14 +01:00
return Wlc_PrsWriteErrorMessage ( p , pStr , " Expecting closing parenthesis. " ) ;
2014-09-17 07:08:22 +02:00
* pStr = ' ' ; * pClose = 0 ;
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
fRotating = 1 ;
}
else
{
2015-02-08 07:29:14 +01:00
char * pClose = Wlc_PrsFindClosingParenthesis ( pStr , ' ( ' , ' ) ' ) ;
2014-09-17 07:08:22 +02:00
if ( pClose = = NULL )
2015-02-08 07:29:14 +01:00
return Wlc_PrsWriteErrorMessage ( p , pStr , " Expecting closing parenthesis. " ) ;
2014-09-17 07:08:22 +02:00
* pStr = * pClose = ' ' ;
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
}
2014-09-12 22:40:48 +02:00
}
if ( Wlc_PrsIsDigit ( pStr ) )
{
2014-09-17 07:08:22 +02:00
int Range , Signed ;
2016-02-03 00:43:19 +01:00
pStr = Wlc_PrsReadConstant ( p , pStr , vFanins , & Range , & Signed , pXValue ) ;
2014-09-12 22:40:48 +02:00
if ( pStr = = NULL )
2014-09-17 07:08:22 +02:00
return 0 ;
2014-09-12 22:40:48 +02:00
Type = WLC_OBJ_CONST ;
}
2016-03-11 07:12:52 +01:00
else if ( pStr [ 0 ] = = ' ! ' | | ( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] ! = ' & ' & & pStr [ 1 ] ! = ' | ' & & pStr [ 1 ] ! = ' ^ ' ) | | pStr [ 0 ] = = ' @ ' | | pStr [ 0 ] = = ' # ' )
2014-09-12 22:40:48 +02:00
{
if ( pStr [ 0 ] = = ' ! ' )
Type = WLC_OBJ_LOGIC_NOT ;
2016-03-11 07:12:52 +01:00
else if ( pStr [ 0 ] = = ' ~ ' )
2014-09-12 22:40:48 +02:00
Type = WLC_OBJ_BIT_NOT ;
2015-07-15 04:55:05 +02:00
else if ( pStr [ 0 ] = = ' @ ' )
Type = WLC_OBJ_ARI_SQRT ;
2016-02-12 18:46:49 +01:00
else if ( pStr [ 0 ] = = ' # ' )
Type = WLC_OBJ_ARI_SQUARE ;
2014-09-12 22:40:48 +02:00
else assert ( 0 ) ;
2015-02-08 07:29:14 +01:00
// skip parentheses
2014-09-17 07:08:22 +02:00
pStr = Wlc_PrsSkipSpaces ( pStr + 1 ) ;
if ( pStr [ 0 ] = = ' ( ' )
{
2015-02-08 07:29:14 +01:00
char * pClose = Wlc_PrsFindClosingParenthesis ( pStr , ' ( ' , ' ) ' ) ;
2014-09-17 07:08:22 +02:00
if ( pClose = = NULL )
2015-02-08 07:29:14 +01:00
return Wlc_PrsWriteErrorMessage ( p , pStr , " Expecting closing parenthesis. " ) ;
2014-09-17 07:08:22 +02:00
* pStr = * pClose = ' ' ;
}
if ( ! ( pStr = Wlc_PrsReadName ( p , pStr , vFanins ) ) )
2014-09-12 22:40:48 +02:00
return Wlc_PrsWriteErrorMessage ( p , pStr , " Cannot read name after !. " ) ;
}
2016-03-10 15:03:53 +01:00
else if ( pStr [ 0 ] = = ' - ' | |
pStr [ 0 ] = = ' & ' | | pStr [ 0 ] = = ' | ' | | pStr [ 0 ] = = ' ^ ' | |
( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' & ' ) | |
( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' | ' ) | |
( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' ^ ' ) )
2014-09-12 22:40:48 +02:00
{
2016-03-11 07:12:52 +01:00
int shift = 1 ;
2016-03-10 15:03:53 +01:00
if ( pStr [ 0 ] = = ' - ' )
Type = WLC_OBJ_ARI_MINUS ;
else if ( pStr [ 0 ] = = ' & ' )
2014-09-12 22:40:48 +02:00
Type = WLC_OBJ_REDUCT_AND ;
else if ( pStr [ 0 ] = = ' | ' )
Type = WLC_OBJ_REDUCT_OR ;
else if ( pStr [ 0 ] = = ' ^ ' )
Type = WLC_OBJ_REDUCT_XOR ;
2016-03-10 15:03:53 +01:00
else if ( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' & ' )
2016-03-11 07:12:52 +01:00
{ Type = WLC_OBJ_REDUCT_NAND ; shift = 2 ; }
2016-03-10 15:03:53 +01:00
else if ( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' | ' )
2016-03-11 07:12:52 +01:00
{ Type = WLC_OBJ_REDUCT_NOR ; shift = 2 ; }
2016-03-10 15:03:53 +01:00
else if ( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' ^ ' )
2016-03-11 07:12:52 +01:00
{ Type = WLC_OBJ_REDUCT_NXOR ; shift = 2 ; }
2014-09-12 22:40:48 +02:00
else assert ( 0 ) ;
2016-03-11 07:12:52 +01:00
if ( ! ( pStr = Wlc_PrsReadName ( p , pStr + shift , vFanins ) ) )
2014-09-18 00:14:17 +02:00
return Wlc_PrsWriteErrorMessage ( p , pStr , " Cannot read name after a unary operator. " ) ;
2014-09-12 22:40:48 +02:00
}
else if ( pStr [ 0 ] = = ' { ' )
{
2014-09-17 07:08:22 +02:00
// THIS IS A HACK TO DETECT zero padding AND sign extension
2014-09-12 22:40:48 +02:00
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 )
{
2014-09-17 07:08:22 +02:00
pStr = Wlc_PrsSkipSpaces ( pStr + 1 ) ;
if ( ! ( pStr = Wlc_PrsReadName ( p , pStr , vFanins ) ) )
2014-09-12 22:40:48 +02:00
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. " ) ;
2014-09-24 15:05:40 +02:00
assert ( Vec_IntSize ( vFanins ) = = 3 ) ;
ABC_SWAP ( int , Vec_IntArray ( vFanins ) [ 1 ] , Vec_IntArray ( vFanins ) [ 2 ] ) ;
2014-09-12 22:40:48 +02:00
Type = WLC_OBJ_MUX ;
}
else if ( pStr [ 0 ] = = ' [ ' )
{
2015-08-04 01:24:10 +02:00
int End , Beg ; char * pLine = pStr ;
2014-09-12 22:40:48 +02:00
pStr = Wlc_PrsFindRange ( pStr , & End , & Beg ) ;
2015-08-04 01:24:10 +02:00
if ( pStr = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pLine , " Non-standard range. " ) ;
2016-04-05 03:09:41 +02:00
Vec_IntPushTwo ( vFanins , End , Beg ) ;
2014-09-12 22:40:48 +02:00
Type = WLC_OBJ_BIT_SELECT ;
}
else
{
2014-09-18 00:14:17 +02:00
if ( pStr [ 0 ] = = ' > ' & & pStr [ 1 ] = = ' > ' & & pStr [ 2 ] ! = ' > ' ) pStr + = 2 , Type = fRotating ? WLC_OBJ_ROTATE_R : WLC_OBJ_SHIFT_R ;
2014-09-12 22:40:48 +02:00
else if ( pStr [ 0 ] = = ' > ' & & pStr [ 1 ] = = ' > ' & & pStr [ 2 ] = = ' > ' ) pStr + = 3 , Type = WLC_OBJ_SHIFT_RA ;
2014-09-18 00:14:17 +02:00
else if ( pStr [ 0 ] = = ' < ' & & pStr [ 1 ] = = ' < ' & & pStr [ 2 ] ! = ' < ' ) pStr + = 2 , Type = fRotating ? WLC_OBJ_ROTATE_L : WLC_OBJ_SHIFT_L ;
2014-09-12 22:40:48 +02:00
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 ;
2016-05-21 05:38:43 +02:00
else if ( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' & ' ) pStr + = 2 , Type = WLC_OBJ_BIT_NAND ;
else if ( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' | ' ) pStr + = 2 , Type = WLC_OBJ_BIT_NOR ;
2016-03-18 06:58:22 +01:00
else if ( pStr [ 0 ] = = ' ~ ' & & pStr [ 1 ] = = ' ^ ' ) pStr + = 2 , Type = WLC_OBJ_BIT_NXOR ;
2016-05-22 05:08:05 +02:00
else if ( pStr [ 0 ] = = ' = ' & & pStr [ 1 ] = = ' > ' ) pStr + = 2 , Type = WLC_OBJ_LOGIC_IMPL ;
2014-09-12 22:40:48 +02:00
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 ;
2016-05-21 05:38:43 +02:00
else if ( pStr [ 0 ] = = ' ^ ' & & pStr [ 1 ] = = ' ^ ' ) pStr + = 2 , Type = WLC_OBJ_LOGIC_XOR ;
2014-09-12 22:40:48 +02:00
else if ( pStr [ 0 ] = = ' = ' & & pStr [ 1 ] = = ' = ' ) pStr + = 2 , Type = WLC_OBJ_COMP_EQU ;
2014-09-18 00:14:17 +02:00
else if ( pStr [ 0 ] = = ' ! ' & & pStr [ 1 ] = = ' = ' ) pStr + = 2 , Type = WLC_OBJ_COMP_NOTEQU ;
2014-09-12 22:40:48 +02:00
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 ;
2016-05-23 19:42:53 +02:00
else if ( pStr [ 0 ] = = ' % ' ) pStr + = 1 , Type = WLC_OBJ_ARI_REM ;
2014-09-12 22:40:48 +02:00
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 ;
2015-06-24 00:53:41 +02:00
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
2018-02-24 18:50:24 +01:00
if ( Type = = WLC_OBJ_ARI_ADD & & pStr [ 0 ] = = ' + ' )
{
if ( ! ( pStr = Wlc_PrsReadName ( p , pStr + 1 , vFanins ) ) )
return 0 ;
pStr = Wlc_PrsSkipSpaces ( pStr ) ;
}
2015-06-24 00:53:41 +02:00
if ( pStr [ 0 ] )
printf ( " Warning: Trailing symbols \" %s \" in line %d. \n " , pStr , Wlc_PrsFindLine ( p , pStr ) ) ;
2014-09-12 22:40:48 +02:00
}
}
// 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 ;
}
2014-09-17 07:08:22 +02:00
int Wlc_PrsReadDeclaration ( Wlc_Prs_t * p , char * pStart )
{
2015-08-04 01:24:10 +02:00
int fFound = 0 , Type = WLC_OBJ_NONE , iObj ; char * pLine ;
2014-09-27 01:11:36 +02:00
int Signed = 0 , Beg = 0 , End = 0 , NameId , fIsPo = 0 ;
2014-09-17 07:08:22 +02:00
if ( Wlc_PrsStrCmp ( pStart , " input " ) )
2014-09-27 01:11:36 +02:00
pStart + = strlen ( " input " ) , Type = WLC_OBJ_PI ;
2014-09-17 07:08:22 +02:00
else if ( Wlc_PrsStrCmp ( pStart , " output " ) )
2014-09-27 01:11:36 +02:00
pStart + = strlen ( " output " ) , fIsPo = 1 ;
2014-09-17 07:08:22 +02:00
pStart = Wlc_PrsSkipSpaces ( pStart ) ;
if ( Wlc_PrsStrCmp ( pStart , " wire " ) )
pStart + = strlen ( " wire " ) ;
2014-09-24 06:22:18 +02:00
else if ( Wlc_PrsStrCmp ( pStart , " reg " ) )
pStart + = strlen ( " reg " ) ;
2014-09-17 07:08:22 +02:00
// read 'signed'
pStart = Wlc_PrsFindWord ( pStart , " signed " , & Signed ) ;
// read range
2015-08-04 01:24:10 +02:00
pLine = pStart ;
2014-09-17 07:08:22 +02:00
pStart = Wlc_PrsFindRange ( pStart , & End , & Beg ) ;
if ( pStart = = NULL )
2015-08-04 01:24:10 +02:00
return Wlc_PrsWriteErrorMessage ( p , pLine , " Non-standard range. " ) ;
2016-04-05 03:09:41 +02:00
if ( End ! = 0 & & Beg ! = 0 )
{
if ( p - > nNonZero [ 0 ] + + = = 0 )
{
p - > nNonZero [ 1 ] = End ;
p - > nNonZero [ 2 ] = Beg ;
p - > nNonZero [ 3 ] = Wlc_PrsFindLine ( p , pStart ) ;
}
}
if ( End < 0 | | Beg < 0 )
2015-07-17 02:37:48 +02:00
{
2016-04-05 03:09:41 +02:00
if ( p - > nNegative [ 0 ] + + = = 0 )
2015-07-17 02:37:48 +02:00
{
2016-04-05 03:09:41 +02:00
p - > nNegative [ 1 ] = End ;
p - > nNegative [ 2 ] = Beg ;
p - > nNegative [ 3 ] = Wlc_PrsFindLine ( p , pStart ) ;
}
}
if ( End < Beg )
{
if ( p - > nReverse [ 0 ] + + = = 0 )
{
p - > nReverse [ 1 ] = End ;
p - > nReverse [ 2 ] = Beg ;
p - > nReverse [ 3 ] = Wlc_PrsFindLine ( p , pStart ) ;
2015-07-17 02:37:48 +02:00
}
}
2014-09-17 07:08:22 +02:00
while ( 1 )
{
2016-02-03 00:43:19 +01:00
char * pName ; int XValue ;
2014-09-17 07:08:22 +02:00
// read name
pStart = Wlc_PrsFindName ( pStart , & pName ) ;
if ( pStart = = NULL )
2014-10-11 04:17:19 +02:00
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name in declaration. " ) ;
2014-09-17 07:08:22 +02:00
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 ) ;
2014-09-27 01:11:36 +02:00
if ( fIsPo ) Wlc_ObjSetCo ( p - > pNtk , Wlc_NtkObj ( p - > pNtk , iObj ) , 0 ) ;
2014-09-17 07:08:22 +02:00
assert ( iObj = = NameId ) ;
// check next definition
pStart = Wlc_PrsSkipSpaces ( pStart ) ;
if ( pStart [ 0 ] = = ' , ' )
{
pStart + + ;
continue ;
}
// check definition
2016-02-03 00:43:19 +01:00
Type = Wlc_PrsFindDefinition ( p , pStart , p - > vFanins , & XValue ) ;
2014-09-17 07:08:22 +02:00
if ( Type )
{
Wlc_Obj_t * pObj = Wlc_NtkObj ( p - > pNtk , iObj ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , Type ) ;
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
2016-02-03 00:43:19 +01:00
pObj - > fXConst = XValue ;
2014-09-17 07:08:22 +02:00
}
break ;
}
return 1 ;
}
2014-09-12 22:40:48 +02:00
int Wlc_PrsDerive ( Wlc_Prs_t * p )
{
2014-09-27 01:11:36 +02:00
Wlc_Obj_t * pObj ;
2014-09-12 22:40:48 +02:00
char * pStart , * pName ;
int i ;
// go through the directives
Wlc_PrsForEachLine ( p , pStart , i )
{
2014-09-24 06:22:18 +02:00
startword :
2014-09-12 22:40:48 +02:00
if ( Wlc_PrsStrCmp ( pStart , " module " ) )
{
// get module name
2014-10-11 04:17:19 +02:00
pName = Wlc_PrsStrtok ( pStart + strlen ( " module " ) , " \r \n \t (,) " ) ;
2014-09-12 22:40:48 +02:00
if ( pName = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read model name. " ) ;
2014-09-27 01:11:36 +02:00
// THIS IS A HACK to skip definitions of modules beginning with "CPL_"
if ( Wlc_PrsStrCmp ( pName , " CPL_ " ) )
{
while ( + + i < Vec_IntSize ( p - > vStarts ) )
{
pStart = Wlc_PrsStr ( p , Vec_IntEntry ( p - > vStarts , i ) ) ;
pStart = strstr ( pStart , " endmodule " ) ;
if ( pStart ! = NULL )
break ;
}
continue ;
}
2014-09-17 07:08:22 +02:00
if ( Wlc_PrsStrCmp ( pName , " table " ) )
{
2014-09-27 01:11:36 +02:00
// THIS IS A HACK to detect table module descriptions
2014-09-18 00:20:04 +02:00
int Width1 = - 1 , Width2 = - 1 ;
int v , b , Value , nBits , nInts ;
unsigned * pTable ;
2014-09-17 07:08:22 +02:00
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 ;
2014-09-18 00:14:17 +02:00
Width1 = atoi ( pStart - 1 ) ;
2014-09-17 07:08:22 +02:00
pStart = Wlc_PrsFindSymbol ( pStart + 2 , ' \' ' ) ;
if ( pStart = = NULL )
continue ;
2014-09-18 00:14:17 +02:00
Width2 = atoi ( pStart - 1 ) ;
2014-09-17 07:08:22 +02:00
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 ) ;
}
2014-09-18 00:14:17 +02:00
assert ( Width1 = = nBits ) ;
2014-09-17 07:08:22 +02:00
// create bitmap
2014-09-18 00:14:17 +02:00
nInts = Abc_BitWordNum ( Width2 * Vec_IntSize ( vValues ) ) ;
2014-09-17 07:08:22 +02:00
pTable = ( unsigned * ) Mem_FlexEntryFetch ( p - > pMemTable , nInts * sizeof ( unsigned ) ) ;
memset ( pTable , 0 , nInts * sizeof ( unsigned ) ) ;
Vec_IntForEachEntry ( vValues , Value , v )
2014-09-18 00:14:17 +02:00
for ( b = 0 ; b < Width2 ; b + + )
2014-09-17 07:08:22 +02:00
if ( ( Value > > b ) & 1 )
2014-09-18 00:14:17 +02:00
Abc_InfoSetBit ( pTable , v * Width2 + b ) ;
2014-09-17 07:08:22 +02:00
Vec_PtrPush ( p - > vTables , pTable ) ;
Vec_IntFree ( vValues ) ;
continue ;
}
2014-09-12 22:40:48 +02:00
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 ) ;
2014-09-17 07:08:22 +02:00
p - > pNtk - > pMemTable = p - > pMemTable ; p - > pMemTable = NULL ;
p - > pNtk - > vTables = p - > vTables ; p - > vTables = NULL ;
// read the argument definitions
2014-11-15 05:12:20 +01:00
while ( ( pName = Wlc_PrsStrtok ( NULL , " (,) " ) ) )
2014-09-17 07:08:22 +02:00
{
pName = Wlc_PrsSkipSpaces ( pName ) ;
if ( Wlc_PrsStrCmp ( pName , " input " ) | | Wlc_PrsStrCmp ( pName , " output " ) | | Wlc_PrsStrCmp ( pName , " wire " ) )
{
if ( ! Wlc_PrsReadDeclaration ( p , pName ) )
return 0 ;
}
}
2014-09-12 22:40:48 +02:00
}
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 ) ;
2015-02-08 07:05:02 +01:00
if ( p - > pNtk - > vInits )
{
// move FO/FI to be part of CI/CO
assert ( ( Vec_IntSize ( & p - > pNtk - > vFfs ) & 1 ) = = 0 ) ;
assert ( Vec_IntSize ( & p - > pNtk - > vFfs ) = = 2 * Vec_IntSize ( p - > pNtk - > vInits ) ) ;
Wlc_NtkForEachFf ( p - > pNtk , pObj , i )
if ( i & 1 )
Wlc_ObjSetCo ( p - > pNtk , pObj , 1 ) ;
else
Wlc_ObjSetCi ( p - > pNtk , pObj ) ;
Vec_IntClear ( & p - > pNtk - > vFfs ) ;
// convert init values into binary string
//Vec_IntPrint( &p->pNtk->vInits );
p - > pNtk - > pInits = Wlc_PrsConvertInitValues ( p - > pNtk ) ;
//printf( "%s", p->pNtk->pInits );
}
2018-04-16 06:23:22 +02:00
if ( p - > vPoPairs )
{
assert ( Vec_StrEntryLast ( p - > vPoPairs ) = = 0 ) ;
Vec_StrPush ( p - > vPoPairs , 0 ) ;
pName = Vec_StrArray ( p - > vPoPairs ) ;
while ( * pName )
{
Wlc_NtkForEachPo ( p - > pNtk , pObj , i )
if ( ! strcmp ( Wlc_ObjName ( p - > pNtk , Wlc_ObjId ( p - > pNtk , pObj ) ) , pName ) )
{
Vec_IntPush ( & p - > pNtk - > vPoPairs , i ) ;
break ;
}
assert ( i < Wlc_NtkPoNum ( p - > pNtk ) ) ;
pName + = strlen ( pName ) + 1 ;
}
assert ( Vec_IntSize ( & p - > pNtk - > vPoPairs ) % 2 = = 0 ) ;
printf ( " Finished parsing %d output pairs to be checked for equivalence. \n " , Vec_IntSize ( & p - > pNtk - > vPoPairs ) / 2 ) ;
}
2014-09-12 22:40:48 +02:00
break ;
}
// these are read as part of the interface
2014-09-24 06:22:18 +02:00
else if ( Wlc_PrsStrCmp ( pStart , " input " ) | | Wlc_PrsStrCmp ( pStart , " output " ) | | Wlc_PrsStrCmp ( pStart , " wire " ) | | Wlc_PrsStrCmp ( pStart , " reg " ) )
2014-09-12 22:40:48 +02:00
{
2014-09-17 07:08:22 +02:00
if ( ! Wlc_PrsReadDeclaration ( p , pStart ) )
return 0 ;
2014-09-12 22:40:48 +02:00
}
else if ( Wlc_PrsStrCmp ( pStart , " assign " ) )
{
2016-02-03 00:43:19 +01:00
int Type , NameId , fFound , XValue = 0 ;
2014-09-12 22:40:48 +02:00
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
2016-02-03 00:43:19 +01:00
Type = Wlc_PrsFindDefinition ( p , pStart , p - > vFanins , & XValue ) ;
2014-09-12 22:40:48 +02:00
if ( Type )
{
2014-09-27 01:11:36 +02:00
pObj = Wlc_NtkObj ( p - > pNtk , NameId ) ;
2014-09-12 22:40:48 +02:00
Wlc_ObjUpdateType ( p - > pNtk , pObj , Type ) ;
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
2016-02-03 00:43:19 +01:00
pObj - > fXConst = XValue ;
2014-09-12 22:40:48 +02:00
}
else
return 0 ;
}
2014-09-17 07:08:22 +02:00
else if ( Wlc_PrsStrCmp ( pStart , " table " ) )
{
2014-09-27 01:11:36 +02:00
// THIS IS A HACK to detect tables
2014-09-17 07:08:22 +02:00
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 ) ;
2014-09-27 01:11:36 +02:00
pObj = Wlc_NtkObj ( p - > pNtk , NameId ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , WLC_OBJ_TABLE ) ;
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
2014-09-17 07:08:22 +02:00
}
2014-09-24 06:22:18 +02:00
else if ( Wlc_PrsStrCmp ( pStart , " always " ) )
{
2014-09-27 01:11:36 +02:00
// THIS IS A HACK to detect always statement representing combinational MUX
2015-12-08 01:17:17 +01:00
int NameId , NameIdOut = - 1 , fFound , nValues , fDefaultFound = 0 ;
2014-09-24 06:22:18 +02:00
// find control
pStart = Wlc_PrsFindWord ( pStart , " case " , & fFound ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read case statement. " ) ;
// read the name
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read table. " ) ;
pStart = Wlc_PrsFindSymbol ( pStart + 1 , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read table. " ) ;
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name after case. " ) ;
NameId = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
Vec_IntClear ( p - > vFanins ) ;
Vec_IntPush ( p - > vFanins , NameId ) ;
// read data inputs
2015-12-08 01:17:17 +01:00
pObj = Wlc_NtkObj ( p - > pNtk , NameId ) ;
if ( pObj = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot find the object in case statement. " ) ;
// remember the number of values
nValues = ( 1 < < Wlc_ObjRange ( pObj ) ) ;
2014-09-24 06:22:18 +02:00
while ( 1 )
2015-12-08 01:17:17 +01:00
{
2014-09-24 06:22:18 +02:00
// find opening
pStart = Wlc_PrsFindSymbol ( pStart , ' : ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot find colon in the case statement. " ) ;
// find output name
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name after case. " ) ;
NameIdOut = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
// find equality
pStart = Wlc_PrsFindSymbol ( pStart , ' = ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot find equality in the case statement. " ) ;
// find input name
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
pStart = Wlc_PrsReadName ( p , pStart , p - > vFanins ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside case statement. " ) ;
2015-12-08 01:17:17 +01:00
// consider default
if ( fDefaultFound )
{
int EntryLast = Vec_IntEntryLast ( p - > vFanins ) ;
2015-12-14 09:44:33 +01:00
if ( nValues ! = Vec_IntSize ( p - > vFanins ) - 2 )
Vec_IntFillExtra ( p - > vFanins , nValues + 1 , EntryLast ) ;
else
Vec_IntPop ( p - > vFanins ) ;
2015-12-08 01:17:17 +01:00
// get next line and check its opening character
pStart = Wlc_PrsStr ( p , Vec_IntEntry ( p - > vStarts , + + i ) ) ;
pStart = Wlc_PrsSkipSpaces ( pStart ) ;
}
else
2014-09-24 06:22:18 +02:00
{
2015-12-08 01:17:17 +01:00
// get next line and check its opening character
2014-09-24 06:22:18 +02:00
pStart = Wlc_PrsStr ( p , Vec_IntEntry ( p - > vStarts , + + i ) ) ;
2015-12-08 01:17:17 +01:00
pStart = Wlc_PrsSkipSpaces ( pStart ) ;
if ( Wlc_PrsIsDigit ( pStart ) )
continue ;
if ( Wlc_PrsStrCmp ( pStart , " default " ) )
{
fDefaultFound = 1 ;
continue ;
}
2014-09-24 06:22:18 +02:00
}
// find closing
pStart = Wlc_PrsFindWord ( pStart , " endcase " , & fFound ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read case statement. " ) ;
// find closing
pStart = Wlc_PrsFindWord ( pStart , " end " , & fFound ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read case statement. " ) ;
pStart = Wlc_PrsSkipSpaces ( pStart ) ;
break ;
}
// check range of the control
2018-11-19 06:01:30 +01:00
if ( nValues < Vec_IntSize ( p - > vFanins ) - 1 ) // may occur if default is not there
{
//return Wlc_PrsWriteErrorMessage( p, pStart, "The number of values in the case statement is wrong.", pName );
printf ( " Warning: The number of values in the case statement is wrong. \n " ) ;
Vec_IntShrink ( p - > vFanins , nValues + 1 ) ;
}
else if ( nValues > Vec_IntSize ( p - > vFanins ) - 1 )
2014-09-27 01:11:36 +02:00
return Wlc_PrsWriteErrorMessage ( p , pStart , " The number of values in the case statement is wrong. " , pName ) ;
2015-07-08 07:34:21 +02:00
if ( Wlc_ObjRange ( pObj ) = = 1 )
2016-04-05 03:09:41 +02:00
{
// return Wlc_PrsWriteErrorMessage( p, pStart, "Always-statement with 1-bit control is not bit-blasted correctly.", pName );
printf ( " Warning: Case-statement with 1-bit control is treated as a 2:1 MUX (correct for unsigned signals only). \n " ) ;
}
2014-09-27 01:11:36 +02:00
pObj = Wlc_NtkObj ( p - > pNtk , NameIdOut ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , WLC_OBJ_MUX ) ;
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
goto startword ;
}
else if ( Wlc_PrsStrCmp ( pStart , " CPL_FF " ) )
{
2015-01-25 20:21:36 +01:00
int NameId = - 1 , NameIdIn = - 1 , NameIdOut = - 1 , fFound , nBits = 1 , fFlopIn , fFlopOut ;
2014-09-27 01:11:36 +02:00
pStart + = strlen ( " CPL_FF " ) ;
if ( pStart [ 0 ] = = ' # ' )
nBits = atoi ( pStart + 1 ) ;
// read names
while ( 1 )
2014-09-24 06:22:18 +02:00
{
2014-09-27 01:11:36 +02:00
pStart = Wlc_PrsFindSymbol ( pStart , ' . ' ) ;
if ( pStart = = NULL )
break ;
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
2015-01-22 02:43:46 +01:00
if ( pStart [ 0 ] ! = ' d ' & & ( pStart [ 0 ] ! = ' q ' | | pStart [ 1 ] = = ' b ' ) & & strncmp ( pStart , " arstval " , 7 ) )
2014-09-27 01:11:36 +02:00
continue ;
2015-01-25 20:21:36 +01:00
fFlopIn = ( pStart [ 0 ] = = ' d ' ) ;
fFlopOut = ( pStart [ 0 ] = = ' q ' ) ;
2014-09-27 01:11:36 +02:00
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
2015-02-08 07:29:14 +01:00
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read opening parenthesis in the flop description. " ) ;
2014-09-27 01:11:36 +02:00
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside flop description. " ) ;
2015-01-25 20:21:36 +01:00
if ( fFlopIn )
2015-01-22 02:43:46 +01:00
NameIdIn = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
2015-01-25 20:21:36 +01:00
else if ( fFlopOut )
NameIdOut = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
2015-01-22 02:43:46 +01:00
else
2014-09-27 01:11:36 +02:00
NameId = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
2014-09-24 06:22:18 +02:00
}
2015-01-22 02:43:46 +01:00
if ( NameIdIn = = - 1 | | NameIdOut = = - 1 )
2014-09-27 01:11:36 +02:00
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name of flop input or flop output is missing. " ) ;
// create flop output
2015-01-25 20:21:36 +01:00
pObj = Wlc_NtkObj ( p - > pNtk , NameIdOut ) ;
2014-09-27 01:11:36 +02:00
Wlc_ObjUpdateType ( p - > pNtk , pObj , WLC_OBJ_FO ) ;
2015-01-25 20:21:36 +01:00
Vec_IntPush ( & p - > pNtk - > vFfs , NameIdOut ) ;
2018-04-16 06:23:22 +02:00
//if ( nBits != Wlc_ObjRange(pObj) )
// printf( "Warning! Flop output \"%s\" has bit-width (%d) that differs from the flop declaration (%d)\n", Abc_NamStr(p->pNtk->pManName, NameIdOut), Wlc_ObjRange(pObj), nBits );
2014-09-27 01:11:36 +02:00
// create flop input
2015-01-25 20:21:36 +01:00
pObj = Wlc_NtkObj ( p - > pNtk , NameIdIn ) ;
Vec_IntPush ( & p - > pNtk - > vFfs , NameIdIn ) ;
2018-04-16 06:23:22 +02:00
//if ( nBits != Wlc_ObjRange(pObj) )
// printf( "Warning! Flop input \"%s\" has bit-width (%d) that differs from the flop declaration (%d)\n", Abc_NamStr(p->pNtk->pManName, NameIdIn), Wlc_ObjRange(pObj), nBits );
2015-01-22 02:43:46 +01:00
// save flop init value
2015-01-25 20:21:36 +01:00
if ( NameId = = - 1 )
printf ( " Initial value of flop \" %s \" is not specified. Zero is assumed. \n " , Abc_NamStr ( p - > pNtk - > pManName , NameIdOut ) ) ;
else
{
pObj = Wlc_NtkObj ( p - > pNtk , NameId ) ;
if ( nBits ! = Wlc_ObjRange ( pObj ) )
2018-04-16 06:23:22 +02:00
printf ( " Warning! Flop init signal \" %s \" bit-width (%d) is different from the flop declaration (%d) \n " , Abc_NamStr ( p - > pNtk - > pManName , NameId ) , Wlc_ObjRange ( pObj ) , nBits ) ;
2015-01-25 20:21:36 +01:00
}
if ( p - > pNtk - > vInits = = NULL )
p - > pNtk - > vInits = Vec_IntAlloc ( 100 ) ;
Vec_IntPush ( p - > pNtk - > vInits , NameId > 0 ? NameId : - nBits ) ;
2018-04-16 06:23:22 +02:00
// printf( "Created flop %s with range %d and init value %d (nameId = %d)\n",
// Abc_NamStr(p->pNtk->pManName, NameIdOut), Wlc_ObjRange(pObj), nBits, NameId );
2014-09-24 06:22:18 +02:00
}
2018-04-30 00:14:01 +02:00
else if ( Wlc_PrsStrCmp ( pStart , " ABC_DFFRSE " ) )
{
2018-09-23 02:40:41 +02:00
int NameId [ 10 ] = { 0 } , fFound , fFlopIn , fFlopClk , fFlopRst , fFlopSet , fFlopEna , fFlopAsync , fFlopSre , fFlopInit , fFlopOut ;
2018-04-30 00:14:01 +02:00
pStart + = strlen ( " ABC_DFF " ) ;
while ( 1 )
{
pStart = Wlc_PrsFindSymbol ( pStart , ' . ' ) ;
if ( pStart = = NULL )
break ;
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
fFlopIn = ( pStart [ 0 ] = = ' d ' ) ;
fFlopClk = ( pStart [ 0 ] = = ' c ' ) ;
fFlopRst = ( pStart [ 0 ] = = ' r ' ) ;
2018-09-23 02:40:41 +02:00
fFlopSet = ( pStart [ 0 ] = = ' s ' & & pStart [ 1 ] = = ' e ' ) ;
2018-04-30 00:14:01 +02:00
fFlopEna = ( pStart [ 0 ] = = ' e ' ) ;
fFlopAsync = ( pStart [ 0 ] = = ' a ' ) ;
2018-09-23 02:40:41 +02:00
fFlopSre = ( pStart [ 0 ] = = ' s ' & & pStart [ 1 ] = = ' r ' ) ;
2018-04-30 00:14:01 +02:00
fFlopInit = ( pStart [ 0 ] = = ' i ' ) ;
2018-09-23 02:40:41 +02:00
fFlopOut = ( pStart [ 0 ] = = ' q ' ) ;
2018-04-30 00:14:01 +02:00
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read opening parenthesis in the flop description. " ) ;
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside flop description. " ) ;
if ( fFlopIn )
NameId [ 0 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fFlopClk )
NameId [ 1 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fFlopRst )
NameId [ 2 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fFlopSet )
NameId [ 3 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fFlopEna )
NameId [ 4 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fFlopAsync )
NameId [ 5 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
2018-09-23 02:40:41 +02:00
else if ( fFlopSre )
2018-04-30 00:14:01 +02:00
NameId [ 6 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
2018-09-23 02:40:41 +02:00
else if ( fFlopInit )
NameId [ 7 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fFlopOut )
NameId [ 8 ] = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
2018-04-30 00:14:01 +02:00
else
assert ( 0 ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
}
if ( NameId [ 0 ] = = - 1 | | NameId [ 7 ] = = - 1 )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name of flop input or flop output is missing. " ) ;
// create output
2018-09-23 02:40:41 +02:00
pObj = Wlc_NtkObj ( p - > pNtk , NameId [ 8 ] ) ;
2018-04-30 00:14:01 +02:00
Wlc_ObjUpdateType ( p - > pNtk , pObj , WLC_OBJ_FF ) ;
Vec_IntClear ( p - > vFanins ) ;
Vec_IntPush ( p - > vFanins , NameId [ 0 ] ) ;
Vec_IntPush ( p - > vFanins , NameId [ 1 ] ) ;
Vec_IntPush ( p - > vFanins , NameId [ 2 ] ) ;
Vec_IntPush ( p - > vFanins , NameId [ 3 ] ) ;
Vec_IntPush ( p - > vFanins , NameId [ 4 ] ) ;
Vec_IntPush ( p - > vFanins , NameId [ 5 ] ) ;
Vec_IntPush ( p - > vFanins , NameId [ 6 ] ) ;
2018-09-23 02:40:41 +02:00
Vec_IntPush ( p - > vFanins , NameId [ 7 ] ) ;
2018-04-30 00:14:01 +02:00
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
}
else if ( Wlc_PrsStrCmp ( pStart , " ABC_DFF " ) )
{
int NameId = - 1 , NameIdIn = - 1 , NameIdOut = - 1 , fFound , nBits = 1 , fFlopIn , fFlopOut ;
pStart + = strlen ( " ABC_DFFRSE " ) ;
while ( 1 )
{
pStart = Wlc_PrsFindSymbol ( pStart , ' . ' ) ;
if ( pStart = = NULL )
break ;
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
fFlopIn = ( pStart [ 0 ] = = ' d ' ) ;
fFlopOut = ( pStart [ 0 ] = = ' q ' ) ;
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read opening parenthesis in the flop description. " ) ;
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside flop description. " ) ;
if ( fFlopIn )
NameIdIn = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fFlopOut )
NameIdOut = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else
NameId = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
}
if ( NameIdIn = = - 1 | | NameIdOut = = - 1 )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name of flop input or flop output is missing. " ) ;
// create flop output
pObj = Wlc_NtkObj ( p - > pNtk , NameIdOut ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , WLC_OBJ_FO ) ;
Vec_IntPush ( & p - > pNtk - > vFfs , NameIdOut ) ;
nBits = Wlc_ObjRange ( Wlc_NtkObj ( p - > pNtk , NameIdOut ) ) ;
// create flop input
pObj = Wlc_NtkObj ( p - > pNtk , NameIdIn ) ;
Vec_IntPush ( & p - > pNtk - > vFfs , NameIdIn ) ;
// compare bit-width
if ( Wlc_ObjRange ( Wlc_NtkObj ( p - > pNtk , NameIdIn ) ) ! = nBits )
printf ( " Warning! Flop input \" %s \" bit-width (%d) is different from that of flop output (%d) \n " ,
Abc_NamStr ( p - > pNtk - > pManName , NameId ) , Wlc_ObjRange ( Wlc_NtkObj ( p - > pNtk , NameIdIn ) ) , nBits ) ;
// save flop init value
if ( NameId = = - 1 )
printf ( " Initial value of flop \" %s \" is not specified. Zero is assumed. \n " , Abc_NamStr ( p - > pNtk - > pManName , NameIdOut ) ) ;
else
{
if ( Wlc_ObjRange ( Wlc_NtkObj ( p - > pNtk , NameId ) ) ! = nBits )
printf ( " Warning! Flop init signal \" %s \" bit-width (%d) is different from that of flop output (%d) \n " ,
Abc_NamStr ( p - > pNtk - > pManName , NameId ) , Wlc_ObjRange ( Wlc_NtkObj ( p - > pNtk , NameId ) ) , nBits ) ;
}
if ( p - > pNtk - > vInits = = NULL )
p - > pNtk - > vInits = Vec_IntAlloc ( 100 ) ;
Vec_IntPush ( p - > pNtk - > vInits , NameId > 0 ? NameId : - Wlc_ObjRange ( Wlc_NtkObj ( p - > pNtk , NameIdOut ) ) ) ;
// printf( "Created flop %s with range %d and init value %d (nameId = %d)\n",
// Abc_NamStr(p->pNtk->pManName, NameIdOut), Wlc_ObjRange(pObj), nBits, NameId );
p - > pNtk - > fEasyFfs = 1 ;
}
2018-03-04 02:57:30 +01:00
else if ( Wlc_PrsStrCmp ( pStart , " CPL_MEM_ " ) )
{
int * pNameId = NULL , NameOutput , NameMi = - 1 , NameMo = - 1 , NameAddr = - 1 , NameDi = - 1 , NameDo = - 1 , fFound , fRead = 1 ;
pStart + = strlen ( " CPL_MEM_ " ) ;
if ( pStart [ 0 ] = = ' W ' )
fRead = 0 ;
// read names
while ( 1 )
{
pStart = Wlc_PrsFindSymbol ( pStart , ' . ' ) ;
if ( pStart = = NULL )
break ;
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
if ( ! strncmp ( pStart , " mem_data_in " , 11 ) )
pNameId = & NameMi ;
else if ( ! strncmp ( pStart , " data_in " , 7 ) )
pNameId = & NameDi ;
else if ( ! strncmp ( pStart , " data_out " , 8 ) )
pNameId = fRead ? & NameDo : & NameMo ;
else if ( ! strncmp ( pStart , " addr_in " , 7 ) )
pNameId = & NameAddr ;
else
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name of the input/output port. " ) ;
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read opening parenthesis in the flop description. " ) ;
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside flop description. " ) ;
* pNameId = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
}
if ( fRead & & ( NameMi = = - 1 | | NameAddr = = - 1 | | NameDo = = - 1 ) )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name of one of signals of read port is missing. " ) ;
if ( ! fRead & & ( NameMi = = - 1 | | NameAddr = = - 1 | | NameDi = = - 1 | | NameMo = = - 1 ) )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name of one of signals of write port is missing. " ) ;
// create output
NameOutput = fRead ? NameDo : NameMo ;
pObj = Wlc_NtkObj ( p - > pNtk , NameOutput ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , fRead ? WLC_OBJ_READ : WLC_OBJ_WRITE ) ;
Vec_IntClear ( p - > vFanins ) ;
Vec_IntPush ( p - > vFanins , NameMi ) ;
Vec_IntPush ( p - > vFanins , NameAddr ) ;
if ( ! fRead )
Vec_IntPush ( p - > vFanins , NameDi ) ;
2018-04-16 06:23:22 +02:00
//printf( "Memory %s ", fRead ? "Read" : "Write" ); printf( "Fanins: " ); Vec_IntPrint( p->vFanins );
2018-03-04 02:57:30 +01:00
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
}
2018-04-30 00:14:01 +02:00
else if ( Wlc_PrsStrCmp ( pStart , " ABC_READ " ) )
{
int * pNameId = NULL , NameMemIn = - 1 , NameData = - 1 , NameAddr = - 1 , fFound ;
pStart + = strlen ( " ABC_READ " ) ;
while ( 1 )
{
pStart = Wlc_PrsFindSymbol ( pStart , ' . ' ) ;
if ( pStart = = NULL )
break ;
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
if ( ! strncmp ( pStart , " mem_in " , 6 ) )
pNameId = & NameMemIn ;
else if ( ! strncmp ( pStart , " addr " , 4 ) )
pNameId = & NameAddr ;
else if ( ! strncmp ( pStart , " data " , 4 ) )
pNameId = & NameData ;
else
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name of the input/output port. " ) ;
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read opening parenthesis in the flop description. " ) ;
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside flop description. " ) ;
* pNameId = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
}
if ( NameMemIn = = - 1 | | NameAddr = = - 1 | | NameData = = - 1 )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name of one of signals of read port is missing. " ) ;
// create output
pObj = Wlc_NtkObj ( p - > pNtk , NameData ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , WLC_OBJ_READ ) ;
Vec_IntClear ( p - > vFanins ) ;
Vec_IntPush ( p - > vFanins , NameMemIn ) ;
Vec_IntPush ( p - > vFanins , NameAddr ) ;
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
p - > pNtk - > fMemPorts = 1 ;
}
else if ( Wlc_PrsStrCmp ( pStart , " ABC_WRITE " ) )
{
int * pNameId = NULL , NameMemIn = - 1 , NameMemOut = - 1 , NameData = - 1 , NameAddr = - 1 , fFound ;
pStart + = strlen ( " ABC_WRITE " ) ;
while ( 1 )
{
pStart = Wlc_PrsFindSymbol ( pStart , ' . ' ) ;
if ( pStart = = NULL )
break ;
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
if ( ! strncmp ( pStart , " mem_in " , 6 ) )
pNameId = & NameMemIn ;
else if ( ! strncmp ( pStart , " mem_out " , 7 ) )
pNameId = & NameMemOut ;
else if ( ! strncmp ( pStart , " data " , 4 ) )
pNameId = & NameData ;
else if ( ! strncmp ( pStart , " addr " , 4 ) )
pNameId = & NameAddr ;
else
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name of the input/output port. " ) ;
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read opening parenthesis in the flop description. " ) ;
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside flop description. " ) ;
* pNameId = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
}
if ( NameMemIn = = - 1 | | NameAddr = = - 1 | | NameData = = - 1 | | NameMemOut = = - 1 )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name of one of signals of write port is missing. " ) ;
// create output
pObj = Wlc_NtkObj ( p - > pNtk , NameMemOut ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , WLC_OBJ_WRITE ) ;
Vec_IntClear ( p - > vFanins ) ;
Vec_IntPush ( p - > vFanins , NameMemIn ) ;
Vec_IntPush ( p - > vFanins , NameAddr ) ;
Vec_IntPush ( p - > vFanins , NameData ) ;
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
p - > pNtk - > fMemPorts = 1 ;
}
2018-11-19 06:01:30 +01:00
else if ( Wlc_PrsStrCmp ( pStart , " CPL_RROT " ) | | Wlc_PrsStrCmp ( pStart , " CPL_LROT " ) )
{
// CPL_RROT #(128, 6) I_47479(.o ( E_46713 ) , .d ( E_46718 ) , .s ( E_46712 ) );
int right_rotation = Wlc_PrsStrCmp ( pStart , " CPL_RROT " ) ;
int NameId = - 1 , NameIdOut = - 1 , NameIdInD = - 1 , NameIdInS = - 1 , fFound , fRotInD , fRotInS , fRotOut ;
pStart + = strlen ( " CPL_RROT " ) ;
// NOTE: no need to parse the parameter values
//if ( pStart[0] == '#' )
// read names
while ( 1 )
{
pStart = Wlc_PrsFindSymbol ( pStart , ' . ' ) ;
if ( pStart = = NULL )
break ;
pStart = Wlc_PrsSkipSpaces ( pStart + 1 ) ;
if ( pStart [ 0 ] ! = ' o ' & & pStart [ 0 ] ! = ' d ' & & pStart [ 0 ] ! = ' s ' )
continue ;
fRotInD = ( pStart [ 0 ] = = ' d ' ) ;
fRotInS = ( pStart [ 0 ] = = ' s ' ) ;
fRotOut = ( pStart [ 0 ] = = ' o ' ) ;
pStart = Wlc_PrsFindSymbol ( pStart , ' ( ' ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read opening parenthesis in the rotation description. " ) ;
pStart = Wlc_PrsFindName ( pStart + 1 , & pName ) ;
if ( pStart = = NULL )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read name inside rotation description. " ) ;
if ( fRotInD )
NameIdInD = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fRotInS )
NameIdInS = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else if ( fRotOut )
NameIdOut = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
else
NameId = Abc_NamStrFindOrAdd ( p - > pNtk - > pManName , pName , & fFound ) ;
if ( ! fFound )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Name %s is not declared. " , pName ) ;
}
if ( NameIdOut = = - 1 | | NameIdInD = = - 1 | | NameIdInS = = - 1 )
return Wlc_PrsWriteErrorMessage ( p , pStart , " Some fields of CPL_ROT are missing. " ) ;
// create rot output
pObj = Wlc_NtkObj ( p - > pNtk , NameIdOut ) ;
Wlc_ObjUpdateType ( p - > pNtk , pObj , right_rotation ? WLC_OBJ_ROTATE_R : WLC_OBJ_ROTATE_L ) ;
Vec_IntClear ( p - > vFanins ) ;
Vec_IntPush ( p - > vFanins , NameIdInD ) ;
Vec_IntPush ( p - > vFanins , NameIdInS ) ;
Wlc_ObjAddFanins ( p - > pNtk , pObj , p - > vFanins ) ;
}
2018-03-04 02:57:30 +01:00
else if ( pStart [ 0 ] = = ' ( ' & & pStart [ 1 ] = = ' * ' ) // skip comments
{
while ( * pStart + + ! = ' ) ' ) ;
pStart = Wlc_PrsSkipSpaces ( pStart ) ;
goto startword ;
}
2014-09-27 01:11:36 +02:00
else if ( pStart [ 0 ] ! = ' ` ' )
2014-09-12 22:40:48 +02:00
{
2018-03-04 02:57:30 +01:00
int iLine = Wlc_PrsFindLine ( p , pStart ) ;
2014-09-12 22:40:48 +02:00
pStart = Wlc_PrsFindName ( pStart , & pName ) ;
2018-03-04 02:57:30 +01:00
return Wlc_PrsWriteErrorMessage ( p , pStart , " Cannot read line %d beginning with %s. " , iLine , ( ! pName | | ! pName [ 0 ] ) ? " \" ? \" " : pName ) ;
2014-09-12 22:40:48 +02:00
}
}
2016-04-05 03:09:41 +02:00
if ( p - > nNonZero [ 0 ] )
{
printf ( " Warning: Input file contains %d objects with non-zero-based ranges. \n " , p - > nNonZero [ 0 ] ) ;
printf ( " For example, signal with range [%d:%d] is declared in line %d. \n " , p - > nNonZero [ 1 ] , p - > nNonZero [ 2 ] , p - > nNonZero [ 3 ] ) ;
}
if ( p - > nNegative [ 0 ] )
{
printf ( " Warning: Input file contains %d objects with negative ranges. \n " , p - > nNegative [ 0 ] ) ;
printf ( " For example, signal with range [%d:%d] is declared in line %d. \n " , p - > nNegative [ 1 ] , p - > nNegative [ 2 ] , p - > nNegative [ 3 ] ) ;
}
if ( p - > nReverse [ 0 ] )
2015-07-17 02:37:48 +02:00
{
2016-04-05 03:09:41 +02:00
printf ( " Warning: Input file contains %d objects with reversed ranges. \n " , p - > nReverse [ 0 ] ) ;
printf ( " For example, signal with range [%d:%d] is declared in line %d. \n " , p - > nReverse [ 1 ] , p - > nReverse [ 2 ] , p - > nReverse [ 3 ] ) ;
2015-07-17 02:37:48 +02:00
}
2014-09-12 22:40:48 +02:00
return 1 ;
}
2016-10-07 07:04:11 +02:00
Wlc_Ntk_t * Wlc_ReadVer ( char * pFileName , char * pStr )
2014-09-12 22:40:48 +02:00
{
Wlc_Prs_t * p ;
Wlc_Ntk_t * pNtk = NULL ;
2016-10-07 07:04:11 +02:00
// either file name or string is given
assert ( ( pFileName = = NULL ) ! = ( pStr = = NULL ) ) ;
2014-09-12 22:40:48 +02:00
// start the parser
2016-10-07 07:04:11 +02:00
p = Wlc_PrsStart ( pFileName , pStr ) ;
2014-09-12 22:40:48 +02:00
if ( p = = NULL )
return NULL ;
// detect lines
if ( ! Wlc_PrsPrepare ( p ) )
goto finish ;
// parse models
if ( ! Wlc_PrsDerive ( p ) )
goto finish ;
// derive topological order
2018-04-16 06:23:22 +02:00
if ( p - > pNtk )
{
2018-09-23 02:40:41 +02:00
Wlc_Obj_t * pObj ; int i ;
Wlc_NtkForEachObj ( p - > pNtk , pObj , i )
if ( pObj - > Type = = WLC_OBJ_FF )
Vec_IntPush ( & p - > pNtk - > vFfs2 , Wlc_ObjId ( p - > pNtk , pObj ) ) ;
2018-04-16 06:23:22 +02:00
pNtk = Wlc_NtkDupDfs ( p - > pNtk , 0 , 1 ) ;
pNtk - > pSpec = Abc_UtilStrsav ( pFileName ) ;
}
2014-09-12 22:40:48 +02:00
finish :
Wlc_PrsPrintErrorMessage ( p ) ;
Wlc_PrsStop ( p ) ;
return pNtk ;
}
/**Function*************************************************************
Synopsis [ ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Io_ReadWordTest ( char * pFileName )
{
Gia_Man_t * pNew ;
2016-10-07 07:04:11 +02:00
Wlc_Ntk_t * pNtk = Wlc_ReadVer ( pFileName , NULL ) ;
2014-09-12 22:40:48 +02:00
if ( pNtk = = NULL )
return ;
2015-07-08 07:34:21 +02:00
Wlc_WriteVer ( pNtk , " test.v " , 0 , 0 ) ;
2014-09-12 22:40:48 +02:00
2018-03-01 03:45:44 +01:00
pNew = Wlc_NtkBitBlast ( pNtk , NULL ) ;
2014-09-12 22:40:48 +02:00
Gia_AigerWrite ( pNew , " test.aig " , 0 , 0 ) ;
Gia_ManStop ( pNew ) ;
Wlc_NtkFree ( pNtk ) ;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END