2014-11-29 23:36:26 +01:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
|
|
|
|
FileName [cbaReadVer.c]
|
|
|
|
|
|
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
|
|
2015-02-01 04:52:32 +01:00
|
|
|
PackageName [Hierarchical word-level netlist.]
|
2014-11-29 23:36:26 +01:00
|
|
|
|
2015-02-01 04:52:32 +01:00
|
|
|
Synopsis [BLIF writer.]
|
2014-11-29 23:36:26 +01:00
|
|
|
|
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
|
|
|
|
Date [Ver. 1.0. Started - November 29, 2014.]
|
|
|
|
|
|
|
|
|
|
Revision [$Id: cbaReadVer.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "cba.h"
|
|
|
|
|
#include "cbaPrs.h"
|
|
|
|
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Verilog keywords
|
|
|
|
|
typedef enum {
|
2015-02-01 04:52:32 +01:00
|
|
|
PRS_VER_NONE = 0, // 0: unused
|
|
|
|
|
PRS_VER_MODULE, // 1: module
|
|
|
|
|
PRS_VER_INOUT, // 2: inout
|
|
|
|
|
PRS_VER_INPUT, // 3: input
|
|
|
|
|
PRS_VER_OUTPUT, // 4: output
|
|
|
|
|
PRS_VER_WIRE, // 5: wire
|
|
|
|
|
PRS_VER_ASSIGN, // 6: assign
|
|
|
|
|
PRS_VER_REG, // 7: reg
|
|
|
|
|
PRS_VER_ALWAYS, // 8: always
|
|
|
|
|
PRS_VER_DEFPARAM, // 9: always
|
|
|
|
|
PRS_VER_BEGIN, // 10: begin
|
|
|
|
|
PRS_VER_END, // 11: end
|
|
|
|
|
PRS_VER_ENDMODULE, // 12: endmodule
|
|
|
|
|
PRS_VER_UNKNOWN // 13: unknown
|
2014-11-29 23:36:26 +01:00
|
|
|
} Cba_VerType_t;
|
|
|
|
|
|
2015-02-01 04:52:32 +01:00
|
|
|
const char * s_VerTypes[PRS_VER_UNKNOWN+1] = {
|
2014-11-29 23:36:26 +01:00
|
|
|
NULL, // 0: unused
|
|
|
|
|
"module", // 1: module
|
|
|
|
|
"inout", // 2: inout
|
|
|
|
|
"input", // 3: input
|
|
|
|
|
"output", // 4: output
|
|
|
|
|
"wire", // 5: wire
|
|
|
|
|
"assign", // 6: assign
|
|
|
|
|
"reg", // 7: reg
|
|
|
|
|
"always", // 8: always
|
|
|
|
|
"defparam", // 9: defparam
|
|
|
|
|
"begin", // 10: begin
|
|
|
|
|
"end", // 11: end
|
|
|
|
|
"endmodule", // 12: endmodule
|
|
|
|
|
NULL // 13: unknown
|
|
|
|
|
};
|
|
|
|
|
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline void Prs_NtkAddVerilogDirectives( Prs_Man_t * p )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for ( i = 1; s_VerTypes[i]; i++ )
|
2015-02-01 04:52:32 +01:00
|
|
|
Abc_NamStrFindOrAdd( p->pStrs, (char *)s_VerTypes[i], NULL );
|
|
|
|
|
assert( Abc_NamObjNumMax(p->pStrs) == i );
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// character recognition
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_CharIsSpace( char c ) { return (c == ' ' || c == '\t' || c == '\r' || c == '\n'); }
|
|
|
|
|
static inline int Prs_CharIsDigit( char c ) { return (c >= '0' && c <= '9'); }
|
|
|
|
|
static inline int Prs_CharIsDigitB( char c ) { return (c == '0' || c == '1' || c == 'x' || c == 'z'); }
|
|
|
|
|
static inline int Prs_CharIsDigitH( char c ) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }
|
|
|
|
|
static inline int Prs_CharIsChar( char c ) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
|
|
|
|
|
static inline int Prs_CharIsSymb1( char c ) { return Prs_CharIsChar(c) || c == '_'; }
|
|
|
|
|
static inline int Prs_CharIsSymb2( char c ) { return Prs_CharIsSymb1(c) || Prs_CharIsDigit(c) || c == '$'; }
|
|
|
|
|
|
|
|
|
|
static inline int Prs_ManIsChar( Prs_Man_t * p, char c ) { return p->pCur[0] == c; }
|
|
|
|
|
static inline int Prs_ManIsChar1( Prs_Man_t * p, char c ) { return p->pCur[1] == c; }
|
|
|
|
|
static inline int Prs_ManIsDigit( Prs_Man_t * p ) { return Prs_CharIsDigit(*p->pCur); }
|
2014-11-29 23:36:26 +01:00
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// FUNCTION DEFINITIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
2014-12-05 03:23:20 +01:00
|
|
|
// collect predefined modules names
|
|
|
|
|
const char * s_KnownModules[100] = {
|
2015-02-01 04:52:32 +01:00
|
|
|
NULL, // CBA_OBJ_NONE = 0, // 0: unused
|
|
|
|
|
NULL, // CBA_OBJ_PI, // 1: input
|
|
|
|
|
NULL, // CBA_OBJ_PO, // 2: output
|
|
|
|
|
NULL, // CBA_OBJ_BI, // 3: box input
|
|
|
|
|
NULL, // CBA_OBJ_BO, // 4: box output
|
|
|
|
|
NULL, // CBA_OBJ_BOX, // 5: box
|
|
|
|
|
|
|
|
|
|
"const0", // CBA_BOX_C0,
|
|
|
|
|
"const1", // CBA_BOX_C1,
|
|
|
|
|
"constX", // CBA_BOX_CX,
|
|
|
|
|
"constZ", // CBA_BOX_CZ,
|
|
|
|
|
"buf", // CBA_BOX_BUF,
|
|
|
|
|
"not", // CBA_BOX_INV,
|
|
|
|
|
"and", // CBA_BOX_AND,
|
|
|
|
|
"nand", // CBA_BOX_NAND,
|
|
|
|
|
"or", // CBA_BOX_OR,
|
|
|
|
|
"nor", // CBA_BOX_NOR,
|
|
|
|
|
"xor", // CBA_BOX_XOR,
|
|
|
|
|
"xnor", // CBA_BOX_XNOR,
|
|
|
|
|
"sharp", // CBA_BOX_SHARP,
|
|
|
|
|
"mux", // CBA_BOX_MUX,
|
|
|
|
|
"maj", // CBA_BOX_MAJ,
|
2014-12-05 03:23:20 +01:00
|
|
|
|
2014-11-29 23:36:26 +01:00
|
|
|
"VERIFIC_",
|
2015-02-01 04:52:32 +01:00
|
|
|
"add_",
|
|
|
|
|
"mult_",
|
|
|
|
|
"div_",
|
|
|
|
|
"mod_",
|
|
|
|
|
"rem_",
|
|
|
|
|
"shift_left_",
|
|
|
|
|
"shift_right_",
|
|
|
|
|
"rotate_left_",
|
|
|
|
|
"rotate_right_",
|
|
|
|
|
"reduce_and_",
|
|
|
|
|
"reduce_or_",
|
|
|
|
|
"reduce_xor_",
|
|
|
|
|
"reduce_nand_",
|
|
|
|
|
"reduce_nor_",
|
|
|
|
|
"reduce_xnor_",
|
|
|
|
|
"LessThan_",
|
|
|
|
|
"Mux_",
|
|
|
|
|
"Select_",
|
|
|
|
|
"Decoder_",
|
|
|
|
|
"EnabledDecoder_",
|
|
|
|
|
"PrioSelect_",
|
|
|
|
|
"DualPortRam_",
|
|
|
|
|
"ReadPort_",
|
|
|
|
|
"WritePort_",
|
|
|
|
|
"ClockedWritePort_",
|
|
|
|
|
"lut",
|
|
|
|
|
"and_",
|
|
|
|
|
"or_",
|
|
|
|
|
"xor_",
|
|
|
|
|
"nand_",
|
|
|
|
|
"nor_",
|
|
|
|
|
"xnor_",
|
|
|
|
|
"buf_",
|
|
|
|
|
"inv_",
|
|
|
|
|
"tri_",
|
|
|
|
|
"sub_",
|
|
|
|
|
"unary_minus_",
|
|
|
|
|
"equal_",
|
|
|
|
|
"not_equal_",
|
|
|
|
|
"mux_",
|
|
|
|
|
"wide_mux_",
|
|
|
|
|
"wide_select_",
|
|
|
|
|
"wide_dff_",
|
|
|
|
|
"wide_dlatch_",
|
|
|
|
|
"wide_dffrs_",
|
|
|
|
|
"wide_dlatchrs_",
|
|
|
|
|
"wide_prio_select_",
|
|
|
|
|
"pow_",
|
|
|
|
|
"PrioEncoder_",
|
|
|
|
|
"abs",
|
2014-11-29 23:36:26 +01:00
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// check if it is a known module
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManIsKnownModule( Prs_Man_t * p, char * pName )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
|
|
|
|
int i;
|
2015-02-01 04:52:32 +01:00
|
|
|
for ( i = CBA_BOX_C0; s_KnownModules[i]; i++ )
|
2014-12-05 03:23:20 +01:00
|
|
|
if ( !strncmp(pName, s_KnownModules[i], strlen(s_KnownModules[i])) )
|
|
|
|
|
return i;
|
2014-11-29 23:36:26 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
2014-12-05 03:23:20 +01:00
|
|
|
// skips Verilog comments (returns 1 if some comments were skipped)
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManUtilSkipComments( Prs_Man_t * p )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( !Prs_ManIsChar(p, '/') )
|
2014-12-05 03:23:20 +01:00
|
|
|
return 0;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar1(p, '/') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
for ( p->pCur += 2; p->pCur < p->pLimit; p->pCur++ )
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, '\n') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{ p->pCur++; return 1; }
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
else if ( Prs_ManIsChar1(p, '*') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
for ( p->pCur += 2; p->pCur < p->pLimit; p->pCur++ )
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, '*') && Prs_ManIsChar1(p, '/') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{ p->pCur++; p->pCur++; return 1; }
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManUtilSkipName( Prs_Man_t * p )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( !Prs_ManIsChar(p, '\\') )
|
2014-12-05 03:23:20 +01:00
|
|
|
return 0;
|
|
|
|
|
for ( p->pCur++; p->pCur < p->pLimit; p->pCur++ )
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, ' ') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{ p->pCur++; return 1; }
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-29 23:36:26 +01:00
|
|
|
// skip any number of spaces and comments
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManUtilSkipSpaces( Prs_Man_t * p )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2014-12-05 03:23:20 +01:00
|
|
|
while ( p->pCur < p->pLimit )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
while ( Prs_CharIsSpace(*p->pCur) )
|
2014-11-29 23:36:26 +01:00
|
|
|
p->pCur++;
|
2014-12-05 03:23:20 +01:00
|
|
|
if ( !*p->pCur )
|
2015-02-01 04:52:32 +01:00
|
|
|
return Prs_ManErrorSet(p, "Unexpectedly reached end-of-file.", 1);
|
|
|
|
|
if ( !Prs_ManUtilSkipComments(p) )
|
2014-12-05 03:23:20 +01:00
|
|
|
return 0;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
return Prs_ManErrorSet(p, "Unexpectedly reached end-of-file.", 1);
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
|
|
|
|
// skip everything including comments until the given char
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManUtilSkipUntil( Prs_Man_t * p, char c )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2014-12-05 03:23:20 +01:00
|
|
|
while ( p->pCur < p->pLimit )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, c) )
|
2014-11-29 23:36:26 +01:00
|
|
|
return 1;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipComments(p) )
|
2014-12-05 03:23:20 +01:00
|
|
|
continue;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipName(p) )
|
2014-12-05 03:23:20 +01:00
|
|
|
continue;
|
2014-11-29 23:36:26 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
// skip everything including comments until the given word
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManUtilSkipUntilWord( Prs_Man_t * p, char * pWord )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
|
|
|
|
char * pPlace = strstr( p->pCur, pWord );
|
2014-12-05 03:23:20 +01:00
|
|
|
if ( pPlace == NULL ) return 1;
|
|
|
|
|
p->pCur = pPlace + strlen(pWord);
|
|
|
|
|
return 0;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadName( Prs_Man_t * p )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
|
|
|
|
char * pStart = p->pCur;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, '\\') ) // escaped name
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
|
|
|
|
pStart = ++p->pCur;
|
2015-02-01 04:52:32 +01:00
|
|
|
while ( !Prs_ManIsChar(p, ' ') )
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
else if ( Prs_CharIsSymb1(*p->pCur) ) // simple name
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
while ( Prs_CharIsSymb2(*p->pCur) )
|
2014-11-29 23:36:26 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
}
|
2014-12-05 03:23:20 +01:00
|
|
|
else
|
|
|
|
|
return 0;
|
2015-02-01 04:52:32 +01:00
|
|
|
return Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur, NULL );
|
2014-12-05 03:23:20 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadNameList( Prs_Man_t * p, Vec_Int_t * vTemp, char LastSymb )
|
|
|
|
|
{
|
|
|
|
|
Vec_IntClear( vTemp );
|
|
|
|
|
while ( 1 )
|
|
|
|
|
{
|
|
|
|
|
int Item = Prs_ManReadName(p);
|
|
|
|
|
if ( Item == 0 ) return Prs_ManErrorSet(p, "Cannot read name in the list.", 0);
|
|
|
|
|
Vec_IntPush( vTemp, Item );
|
|
|
|
|
if ( Prs_ManIsChar(p, LastSymb) ) break;
|
|
|
|
|
if ( !Prs_ManIsChar(p, ',') ) return Prs_ManErrorSet(p, "Expecting comma in the list.", 0);
|
|
|
|
|
p->pCur++;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
static inline int Prs_ManReadConstant( Prs_Man_t * p )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
char * pStart = p->pCur;
|
2015-02-01 04:52:32 +01:00
|
|
|
assert( Prs_ManIsDigit(p) );
|
|
|
|
|
while ( Prs_ManIsDigit(p) )
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( !Prs_ManIsChar(p, '\'') ) return Prs_ManErrorSet(p, "Cannot read constant.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, 'b') )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
while ( Prs_CharIsDigitB(*p->pCur) )
|
2014-11-29 23:36:26 +01:00
|
|
|
p->pCur++;
|
2014-12-05 03:23:20 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
else if ( Prs_ManIsChar(p, 'h') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2014-11-29 23:36:26 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
while ( Prs_CharIsDigitH(*p->pCur) )
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
else if ( Prs_ManIsChar(p, 'd') )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
while ( Prs_ManIsDigit(p) )
|
2014-11-29 23:36:26 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
else return Prs_ManErrorSet(p, "Cannot read radix of constant.", 0);
|
|
|
|
|
return Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur, NULL );
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadRange( Prs_Man_t * p )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
assert( Prs_ManIsChar(p, '[') );
|
2014-12-04 05:35:39 +01:00
|
|
|
Vec_StrClear( &p->vCover );
|
|
|
|
|
Vec_StrPush( &p->vCover, *p->pCur++ );
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( !Prs_ManIsDigit(p) ) return Prs_ManErrorSet(p, "Cannot read digit in range specification.", 0);
|
|
|
|
|
while ( Prs_ManIsDigit(p) )
|
2014-12-04 05:35:39 +01:00
|
|
|
Vec_StrPush( &p->vCover, *p->pCur++ );
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( Prs_ManIsChar(p, ':') )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2014-12-04 05:35:39 +01:00
|
|
|
Vec_StrPush( &p->vCover, *p->pCur++ );
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( !Prs_ManIsDigit(p) ) return Prs_ManErrorSet(p, "Cannot read digit in range specification.", 0);
|
|
|
|
|
while ( Prs_ManIsDigit(p) )
|
2014-12-04 05:35:39 +01:00
|
|
|
Vec_StrPush( &p->vCover, *p->pCur++ );
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( !Prs_ManIsChar(p, ']') ) return Prs_ManErrorSet(p, "Cannot read closing brace in range specification.", 0);
|
2014-12-04 05:35:39 +01:00
|
|
|
Vec_StrPush( &p->vCover, *p->pCur++ );
|
2014-12-05 03:23:20 +01:00
|
|
|
Vec_StrPush( &p->vCover, '\0' );
|
2015-02-01 04:52:32 +01:00
|
|
|
return Abc_NamStrFindOrAdd( p->pStrs, Vec_StrArray(&p->vCover), NULL );
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadConcat( Prs_Man_t * p, Vec_Int_t * vTemp2 )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
extern int Prs_ManReadSignalList( Prs_Man_t * p, Vec_Int_t * vTemp, char LastSymb, int fAddForm );
|
|
|
|
|
assert( Prs_ManIsChar(p, '{') );
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( !Prs_ManReadSignalList( p, vTemp2, '}', 0 ) ) return 0;
|
2014-12-05 03:23:20 +01:00
|
|
|
// check final
|
2015-02-01 04:52:32 +01:00
|
|
|
assert( Prs_ManIsChar(p, '}') );
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
// return special case
|
2015-02-01 04:52:32 +01:00
|
|
|
assert( Vec_IntSize(vTemp2) > 0 );
|
|
|
|
|
if ( Vec_IntSize(vTemp2) == 1 )
|
|
|
|
|
return Vec_IntEntry(vTemp2, 0);
|
|
|
|
|
return Abc_Var2Lit2( Prs_NtkAddConcat(p->pNtk, vTemp2), CBA_PRS_CONCAT );
|
2014-12-05 03:23:20 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadSignal( Prs_Man_t * p )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
int Item;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( Prs_ManIsDigit(p) )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
Item = Prs_ManReadConstant(p);
|
|
|
|
|
if ( Item == 0 ) return 0;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
return Abc_Var2Lit2( Item, CBA_PRS_CONST );
|
|
|
|
|
}
|
|
|
|
|
if ( Prs_ManIsChar(p, '{') )
|
|
|
|
|
{
|
|
|
|
|
if ( p->fUsingTemp2 ) return Prs_ManErrorSet(p, "Cannot read nested concatenations.", 0);
|
|
|
|
|
p->fUsingTemp2 = 1;
|
|
|
|
|
Item = Prs_ManReadConcat(p, &p->vTemp2);
|
|
|
|
|
p->fUsingTemp2 = 0;
|
|
|
|
|
if ( Item == 0 ) return 0;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
return Item;
|
2014-12-05 03:23:20 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
Item = Prs_ManReadName( p );
|
|
|
|
|
if ( Item == 0 ) return 0; // was return 1;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( Prs_ManIsChar(p, '[') )
|
|
|
|
|
{
|
|
|
|
|
int Range = Prs_ManReadRange(p);
|
|
|
|
|
if ( Range == 0 ) return 0;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
return Abc_Var2Lit2( Prs_NtkAddSlice(p->pNtk, Item, Range), CBA_PRS_SLICE );
|
|
|
|
|
}
|
|
|
|
|
return Abc_Var2Lit2( Item, CBA_PRS_NAME );
|
2014-12-05 03:23:20 +01:00
|
|
|
}
|
|
|
|
|
}
|
2015-02-01 05:02:46 +01:00
|
|
|
int Prs_ManReadSignalList( Prs_Man_t * p, Vec_Int_t * vTemp, char LastSymb, int fAddForm )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
Vec_IntClear( vTemp );
|
|
|
|
|
while ( 1 )
|
|
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
int Item = Prs_ManReadSignal(p);
|
|
|
|
|
if ( Item == 0 ) return Prs_ManErrorSet(p, "Cannot read signal in the list.", 0);
|
|
|
|
|
if ( fAddForm )
|
|
|
|
|
Vec_IntPush( vTemp, 0 );
|
|
|
|
|
Vec_IntPush( vTemp, Item );
|
|
|
|
|
if ( Prs_ManIsChar(p, LastSymb) ) break;
|
|
|
|
|
if ( !Prs_ManIsChar(p, ',') ) return Prs_ManErrorSet(p, "Expecting comma in the list.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadSignalList2( Prs_Man_t * p, Vec_Int_t * vTemp )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
int FormId, ActItem;
|
2014-12-05 03:23:20 +01:00
|
|
|
Vec_IntClear( vTemp );
|
2015-02-01 04:52:32 +01:00
|
|
|
assert( Prs_ManIsChar(p, '.') );
|
|
|
|
|
while ( Prs_ManIsChar(p, '.') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
FormId = Prs_ManReadName( p );
|
|
|
|
|
if ( FormId == 0 ) return Prs_ManErrorSet(p, "Cannot read formal name of the instance.", 0);
|
|
|
|
|
if ( !Prs_ManIsChar(p, '(') ) return Prs_ManErrorSet(p, "Cannot read \"(\" in the instance.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
ActItem = Prs_ManReadSignal( p );
|
|
|
|
|
if ( ActItem == 0 ) return Prs_ManErrorSet(p, "Cannot read actual name of the instance.", 0);
|
|
|
|
|
if ( !Prs_ManIsChar(p, ')') ) return Prs_ManErrorSet(p, "Cannot read \")\" in the instance.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_IntPushTwo( vTemp, FormId, ActItem );
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( Prs_ManIsChar(p, ')') ) break;
|
|
|
|
|
if ( !Prs_ManIsChar(p, ',') ) return Prs_ManErrorSet(p, "Expecting comma in the instance.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
2014-12-05 03:23:20 +01:00
|
|
|
}
|
|
|
|
|
assert( Vec_IntSize(vTemp) > 0 );
|
2015-02-01 04:52:32 +01:00
|
|
|
assert( Vec_IntSize(vTemp) % 2 == 0 );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadDeclaration( Prs_Man_t * p, int Type )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
int i, Sig, RangeId = 0;
|
|
|
|
|
Vec_Int_t * vSigs[4] = { &p->pNtk->vInouts, &p->pNtk->vInputs, &p->pNtk->vOutputs, &p->pNtk->vWires };
|
|
|
|
|
Vec_Int_t * vSigsR[4] = { &p->pNtk->vInoutsR, &p->pNtk->vInputsR, &p->pNtk->vOutputsR, &p->pNtk->vWiresR };
|
|
|
|
|
assert( Type >= PRS_VER_INOUT && Type <= PRS_VER_WIRE );
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( Prs_ManIsChar(p, '[') && !(RangeId = Prs_ManReadRange(p)) ) return 0;
|
|
|
|
|
if ( !Prs_ManReadNameList( p, &p->vTemp, ';' ) ) return 0;
|
|
|
|
|
Vec_IntForEachEntry( &p->vTemp, Sig, i )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_IntPush( vSigs[Type - PRS_VER_INOUT], Sig );
|
|
|
|
|
Vec_IntPush( vSigsR[Type - PRS_VER_INOUT], RangeId );
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadAssign( Prs_Man_t * p )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
int OutItem, InItem, fCompl = 0, Oper = 0;
|
2014-12-05 03:23:20 +01:00
|
|
|
// read output name
|
2015-02-01 04:52:32 +01:00
|
|
|
OutItem = Prs_ManReadSignal( p );
|
|
|
|
|
if ( OutItem == 0 ) return Prs_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
|
|
|
|
|
if ( !Prs_ManIsChar(p, '=') ) return Prs_ManErrorSet(p, "Expecting \"=\" in assign-statement.", 0);
|
2014-11-29 23:36:26 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( Prs_ManIsChar(p, '~') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
fCompl = 1;
|
|
|
|
|
p->pCur++;
|
|
|
|
|
}
|
|
|
|
|
// read first name
|
2015-02-01 04:52:32 +01:00
|
|
|
InItem = Prs_ManReadSignal( p );
|
|
|
|
|
if ( InItem == 0 ) return Prs_ManErrorSet(p, "Cannot read first input name in the assign-statement.", 0);
|
|
|
|
|
Vec_IntClear( &p->vTemp );
|
|
|
|
|
Vec_IntPush( &p->vTemp, 0 );
|
|
|
|
|
Vec_IntPush( &p->vTemp, InItem );
|
2014-12-05 03:23:20 +01:00
|
|
|
// check unary operator
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, ';') )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_IntPush( &p->vTemp, 0 );
|
|
|
|
|
Vec_IntPush( &p->vTemp, OutItem );
|
|
|
|
|
Oper = fCompl ? CBA_BOX_INV : CBA_BOX_BUF;
|
|
|
|
|
Prs_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManIsChar(p, '&') )
|
|
|
|
|
Oper = CBA_BOX_AND;
|
|
|
|
|
else if ( Prs_ManIsChar(p, '|') )
|
|
|
|
|
Oper = CBA_BOX_OR;
|
|
|
|
|
else if ( Prs_ManIsChar(p, '^') )
|
|
|
|
|
Oper = fCompl ? CBA_BOX_XNOR : CBA_BOX_XOR;
|
|
|
|
|
else if ( Prs_ManIsChar(p, '?') )
|
|
|
|
|
Oper = CBA_BOX_MUX;
|
|
|
|
|
else return Prs_ManErrorSet(p, "Unrecognized operator in the assign-statement.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
// read second name
|
2015-02-01 04:52:32 +01:00
|
|
|
InItem = Prs_ManReadSignal( p );
|
|
|
|
|
if ( InItem == 0 ) return Prs_ManErrorSet(p, "Cannot read second input name in the assign-statement.", 0);
|
|
|
|
|
Vec_IntPush( &p->vTemp, 0 );
|
|
|
|
|
Vec_IntPush( &p->vTemp, InItem );
|
2014-12-05 03:23:20 +01:00
|
|
|
// read third argument
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Oper == CBA_BOX_MUX )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
assert( fCompl == 0 );
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( !Prs_ManIsChar(p, ':') ) return Prs_ManErrorSet(p, "Expected colon in the MUX assignment.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
|
|
|
|
// read third name
|
2015-02-01 04:52:32 +01:00
|
|
|
InItem = Prs_ManReadSignal( p );
|
|
|
|
|
if ( InItem == 0 ) return Prs_ManErrorSet(p, "Cannot read third input name in the assign-statement.", 0);
|
|
|
|
|
Vec_IntPush( &p->vTemp, 0 );
|
|
|
|
|
Vec_IntPush( &p->vTemp, InItem );
|
|
|
|
|
if ( !Prs_ManIsChar(p, ';') ) return Prs_ManErrorSet(p, "Expected semicolon at the end of the assign-statement.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
}
|
|
|
|
|
// write binary operator
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_IntPush( &p->vTemp, 0 );
|
|
|
|
|
Vec_IntPush( &p->vTemp, OutItem );
|
|
|
|
|
Prs_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 1;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadInstance( Prs_Man_t * p, int Func )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
int InstId, Status;
|
|
|
|
|
/*
|
|
|
|
|
static Counter = 0;
|
|
|
|
|
if ( ++Counter == 7 )
|
|
|
|
|
{
|
|
|
|
|
int s=0;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( (InstId = Prs_ManReadName(p)) )
|
|
|
|
|
if (Prs_ManUtilSkipSpaces(p)) return 0;
|
|
|
|
|
if ( !Prs_ManIsChar(p, '(') ) return Prs_ManErrorSet(p, "Expecting \"(\" in module instantiation.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( Prs_ManIsChar(p, '.') ) // box
|
|
|
|
|
Status = Prs_ManReadSignalList2(p, &p->vTemp);
|
|
|
|
|
else // node
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
//char * s = Abc_NamStr(p->pStrs, Func);
|
|
|
|
|
// translate elementary gate
|
|
|
|
|
int iFuncNew = Prs_ManIsKnownModule(p, Abc_NamStr(p->pStrs, Func));
|
|
|
|
|
if ( iFuncNew == 0 ) return Prs_ManErrorSet(p, "Cannot find elementary gate.", 0);
|
2014-12-05 03:23:20 +01:00
|
|
|
Func = iFuncNew;
|
2015-02-01 04:52:32 +01:00
|
|
|
Status = Prs_ManReadSignalList( p, &p->vTemp, ')', 1 );
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Status == 0 ) return 0;
|
|
|
|
|
assert( Prs_ManIsChar(p, ')') );
|
|
|
|
|
p->pCur++;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( !Prs_ManIsChar(p, ';') ) return Prs_ManErrorSet(p, "Expecting semicolon in the instance.", 0);
|
|
|
|
|
// add box
|
|
|
|
|
Prs_NtkAddBox( p->pNtk, Func, InstId, &p->vTemp );
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
static inline int Prs_ManReadArguments( Prs_Man_t * p )
|
|
|
|
|
{
|
|
|
|
|
int iRange = 0, iType = -1;
|
|
|
|
|
Vec_Int_t * vSigs[3] = { &p->pNtk->vInouts, &p->pNtk->vInputs, &p->pNtk->vOutputs };
|
|
|
|
|
Vec_Int_t * vSigsR[3] = { &p->pNtk->vInoutsR, &p->pNtk->vInputsR, &p->pNtk->vOutputsR };
|
|
|
|
|
assert( Prs_ManIsChar(p, '(') );
|
|
|
|
|
p->pCur++;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
while ( 1 )
|
|
|
|
|
{
|
|
|
|
|
int iName = Prs_ManReadName( p );
|
|
|
|
|
if ( iName == 0 ) return 0;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
if ( iName >= PRS_VER_INOUT && iName <= PRS_VER_OUTPUT ) // declaration
|
|
|
|
|
{
|
|
|
|
|
iType = iName;
|
|
|
|
|
if ( Prs_ManIsChar(p, '[') )
|
|
|
|
|
{
|
|
|
|
|
iRange = Prs_ManReadRange(p);
|
|
|
|
|
if ( iRange == 0 ) return 0;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ( iType > 0 )
|
|
|
|
|
{
|
|
|
|
|
Vec_IntPush( vSigs[iType - PRS_VER_INOUT], iName );
|
|
|
|
|
Vec_IntPush( vSigsR[iType - PRS_VER_INOUT], iRange );
|
|
|
|
|
}
|
|
|
|
|
Vec_IntPush( &p->pNtk->vOrder, iName );
|
|
|
|
|
if ( Prs_ManIsChar(p, ')') )
|
|
|
|
|
break;
|
|
|
|
|
if ( !Prs_ManIsChar(p, ',') ) return Prs_ManErrorSet(p, "Expecting comma in the instance.", 0);
|
|
|
|
|
p->pCur++;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 0;
|
|
|
|
|
}
|
|
|
|
|
// check final
|
|
|
|
|
assert( Prs_ManIsChar(p, ')') );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 1;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
|
|
|
|
// this procedure can return:
|
2014-12-05 03:23:20 +01:00
|
|
|
// 0 = reached end-of-file; 1 = successfully parsed; 2 = recognized as primitive; 3 = failed and skipped; 4 = error (failed and could not skip)
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadModule( Prs_Man_t * p )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2014-12-05 03:23:20 +01:00
|
|
|
int iToken, Status;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( p->pNtk != NULL ) return Prs_ManErrorSet(p, "Parsing previous module is unfinished.", 4);
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_ManErrorClear( p );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 0;
|
|
|
|
|
}
|
2014-11-29 23:36:26 +01:00
|
|
|
// read keyword
|
2015-02-01 04:52:32 +01:00
|
|
|
iToken = Prs_ManReadName( p );
|
|
|
|
|
if ( iToken != PRS_VER_MODULE ) return Prs_ManErrorSet(p, "Cannot read \"module\" keyword.", 4);
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
|
2014-11-29 23:36:26 +01:00
|
|
|
// read module name
|
2015-02-01 04:52:32 +01:00
|
|
|
iToken = Prs_ManReadName( p );
|
|
|
|
|
if ( iToken == 0 ) return Prs_ManErrorSet(p, "Cannot read module name.", 4);
|
|
|
|
|
if ( Prs_ManIsKnownModule(p, Abc_NamStr(p->pStrs, iToken)) )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipUntilWord( p, "endmodule" ) ) return Prs_ManErrorSet(p, "Cannot find \"endmodule\" keyword.", 4);
|
|
|
|
|
//printf( "Warning! Skipped known module \"%s\".\n", Abc_NamStr(p->pStrs, iToken) );
|
|
|
|
|
Vec_IntPush( &p->vKnown, iToken );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 2;
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_ManInitializeNtk( p, iToken, 1 );
|
2014-11-29 23:36:26 +01:00
|
|
|
// skip arguments
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
|
|
|
|
|
if ( !Prs_ManIsChar(p, '(') ) return Prs_ManErrorSet(p, "Cannot find \"(\" in the argument declaration.", 4);
|
|
|
|
|
if ( !Prs_ManReadArguments(p) ) return 4;
|
2014-11-29 23:36:26 +01:00
|
|
|
assert( *p->pCur == ')' );
|
|
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
|
2014-11-29 23:36:26 +01:00
|
|
|
// read declarations and instances
|
2015-02-01 04:52:32 +01:00
|
|
|
while ( Prs_ManIsChar(p, ';') )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
|
|
|
|
p->pCur++;
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
|
|
|
|
|
iToken = Prs_ManReadName( p );
|
|
|
|
|
if ( iToken == PRS_VER_ENDMODULE )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_IntPush( &p->vSucceeded, p->pNtk->iModuleName );
|
|
|
|
|
Prs_ManFinalizeNtk( p );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 1;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( iToken >= PRS_VER_INOUT && iToken <= PRS_VER_WIRE ) // declaration
|
|
|
|
|
Status = Prs_ManReadDeclaration( p, iToken );
|
|
|
|
|
else if ( iToken == PRS_VER_REG || iToken == PRS_VER_DEFPARAM ) // unsupported keywords
|
|
|
|
|
Status = Prs_ManUtilSkipUntil( p, ';' );
|
2014-12-05 03:23:20 +01:00
|
|
|
else // read instance
|
|
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( iToken == PRS_VER_ASSIGN )
|
|
|
|
|
Status = Prs_ManReadAssign( p );
|
2014-12-05 03:23:20 +01:00
|
|
|
else
|
2015-02-01 04:52:32 +01:00
|
|
|
Status = Prs_ManReadInstance( p, iToken );
|
2014-12-05 03:23:20 +01:00
|
|
|
if ( Status == 0 )
|
|
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( Prs_ManUtilSkipUntilWord( p, "endmodule" ) ) return Prs_ManErrorSet(p, "Cannot find \"endmodule\" keyword.", 4);
|
2014-12-05 03:23:20 +01:00
|
|
|
//printf( "Warning! Failed to parse \"%s\". Adding module \"%s\" as blackbox.\n",
|
2015-02-01 04:52:32 +01:00
|
|
|
// Abc_NamStr(p->pStrs, iToken), Abc_NamStr(p->pStrs, p->pNtk->iModuleName) );
|
|
|
|
|
Vec_IntPush( &p->vFailed, p->pNtk->iModuleName );
|
2014-12-05 03:23:20 +01:00
|
|
|
// cleanup
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_IntErase( &p->pNtk->vWires );
|
|
|
|
|
Vec_IntErase( &p->pNtk->vWiresR );
|
|
|
|
|
Vec_IntErase( &p->pNtk->vSlices );
|
|
|
|
|
Vec_IntErase( &p->pNtk->vConcats );
|
|
|
|
|
Vec_IntErase( &p->pNtk->vBoxes );
|
|
|
|
|
Vec_IntErase( &p->pNtk->vObjs );
|
|
|
|
|
p->fUsingTemp2 = 0;
|
2014-12-05 03:23:20 +01:00
|
|
|
// add
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_ManFinalizeNtk( p );
|
|
|
|
|
Prs_ManErrorClear( p );
|
2014-12-05 03:23:20 +01:00
|
|
|
return 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
if ( !Status ) return 4;
|
|
|
|
|
if ( Prs_ManUtilSkipSpaces(p) ) return 4;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
return Prs_ManErrorSet(p, "Cannot find \";\" in the module definition.", 4);
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2015-02-01 04:52:32 +01:00
|
|
|
static inline int Prs_ManReadDesign( Prs_Man_t * p )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
|
|
|
|
while ( 1 )
|
|
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
int RetValue = Prs_ManReadModule( p );
|
2014-12-05 03:23:20 +01:00
|
|
|
if ( RetValue == 0 ) // end of file
|
|
|
|
|
break;
|
|
|
|
|
if ( RetValue == 1 ) // successfully parsed
|
|
|
|
|
continue;
|
|
|
|
|
if ( RetValue == 2 ) // recognized as primitive
|
2014-11-29 23:36:26 +01:00
|
|
|
continue;
|
2014-12-05 03:23:20 +01:00
|
|
|
if ( RetValue == 3 ) // failed and skipped
|
2014-11-29 23:36:26 +01:00
|
|
|
continue;
|
2014-12-05 03:23:20 +01:00
|
|
|
if ( RetValue == 4 ) // error
|
2014-11-29 23:36:26 +01:00
|
|
|
return 0;
|
|
|
|
|
assert( 0 );
|
|
|
|
|
}
|
2014-12-05 03:23:20 +01:00
|
|
|
return 1;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
|
|
|
|
|
2014-12-05 03:23:20 +01:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2015-02-01 04:52:32 +01:00
|
|
|
void Prs_ManPrintModules( Prs_Man_t * p )
|
2014-12-05 03:23:20 +01:00
|
|
|
{
|
|
|
|
|
char * pName; int i;
|
|
|
|
|
printf( "Succeeded parsing %d models:\n", Vec_IntSize(&p->vSucceeded) );
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_ManForEachNameVec( &p->vSucceeded, p, pName, i )
|
2014-12-05 03:23:20 +01:00
|
|
|
printf( " %s", pName );
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
printf( "Skipped %d known models:\n", Vec_IntSize(&p->vKnown) );
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_ManForEachNameVec( &p->vKnown, p, pName, i )
|
2014-12-05 03:23:20 +01:00
|
|
|
printf( " %s", pName );
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
printf( "Skipped %d failed models:\n", Vec_IntSize(&p->vFailed) );
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_ManForEachNameVec( &p->vFailed, p, pName, i )
|
2014-12-05 03:23:20 +01:00
|
|
|
printf( " %s", pName );
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
}
|
2014-11-29 23:36:26 +01:00
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_Ptr_t * Prs_ManReadVerilog( char * pFileName )
|
2015-01-18 05:27:23 +01:00
|
|
|
{
|
2015-02-01 04:52:32 +01:00
|
|
|
Vec_Ptr_t * vPrs = NULL;
|
|
|
|
|
Prs_Man_t * p = Prs_ManAlloc( pFileName );
|
2014-11-29 23:36:26 +01:00
|
|
|
if ( p == NULL )
|
|
|
|
|
return NULL;
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_NtkAddVerilogDirectives( p );
|
|
|
|
|
Prs_ManReadDesign( p );
|
|
|
|
|
//Prs_ManPrintModules( p );
|
|
|
|
|
if ( Prs_ManErrorPrint(p) )
|
|
|
|
|
ABC_SWAP( Vec_Ptr_t *, vPrs, p->vNtks );
|
|
|
|
|
Prs_ManFree( p );
|
|
|
|
|
return vPrs;
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
2014-12-05 03:23:20 +01:00
|
|
|
|
2015-02-01 04:52:32 +01:00
|
|
|
void Prs_ManReadVerilogTest( char * pFileName )
|
2014-11-29 23:36:26 +01:00
|
|
|
{
|
2014-12-05 03:23:20 +01:00
|
|
|
abctime clk = Abc_Clock();
|
2015-02-01 04:52:32 +01:00
|
|
|
extern void Prs_ManWriteVerilog( char * pFileName, Vec_Ptr_t * p );
|
|
|
|
|
Vec_Ptr_t * vPrs = Prs_ManReadVerilog( "c/hie/dump/1/netlist_1.v" );
|
|
|
|
|
// Vec_Ptr_t * vPrs = Prs_ManReadVerilog( "aga/me/me_wide.v" );
|
|
|
|
|
// Vec_Ptr_t * vPrs = Prs_ManReadVerilog( "aga/ray/ray_wide.v" );
|
|
|
|
|
if ( !vPrs ) return;
|
|
|
|
|
printf( "Finished reading %d networks. ", Vec_PtrSize(vPrs) );
|
|
|
|
|
printf( "NameIDs = %d. ", Abc_NamObjNumMax(Prs_ManRoot(vPrs)->pStrs) );
|
|
|
|
|
printf( "Memory = %.2f MB. ", 1.0*Prs_ManMemory(vPrs)/(1<<20) );
|
2014-12-05 03:23:20 +01:00
|
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
2015-02-01 04:52:32 +01:00
|
|
|
Prs_ManWriteVerilog( "c/hie/dump/1/netlist_1_out_new.v", vPrs );
|
|
|
|
|
// Prs_ManWriteVerilog( "aga/me/me_wide_out.v", vPrs );
|
|
|
|
|
// Prs_ManWriteVerilog( "aga/ray/ray_wide_out.v", vPrs );
|
|
|
|
|
// Abc_NamPrint( p->pStrs );
|
|
|
|
|
Prs_ManVecFree( vPrs );
|
2014-11-29 23:36:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|