diff --git a/Changes b/Changes index e9fe8e89f..d0e4609dd 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,10 @@ indicates the contributor was also the author of the fix; Thanks! **** Warn if flex is not installed. [Ralf Karge] +**** Ignore `protect and `endprotect. + +**** Allow empty case/endcase blocks. + * Verilator 3.650 4/20/2007 ** Add --compiler msvc option. This is now required when Verilated code diff --git a/src/V3Case.cpp b/src/V3Case.cpp index a93a4364e..bfc12e181 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -62,9 +62,6 @@ private: //int debug() { return 9; } virtual void visit(AstNodeCase* nodep, AstNUser*) { - // We report a syntax error on empty "case (x) endcase" blocks, so never no items at all - if (!nodep->itemsp()) nodep->v3fatalSrc("No items (not even default) under case statement?\n"); - // Detect multiple defaults bool hitDefault = false; for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) { diff --git a/src/V3PreLex.l b/src/V3PreLex.l index ebf87c30c..a730ac089 100644 --- a/src/V3PreLex.l +++ b/src/V3PreLex.l @@ -57,6 +57,7 @@ static void pslMoreNeeded(bool flag) { V3PreLex::s_currentLexp->m_pslMoreNeeded %x DEFMODE %x ARGMODE %x INCMODE +%x PRTMODE /* drop: Drop Ctrl-Z - can't pass thru or may EOF the output too soon */ @@ -106,6 +107,13 @@ psl [p]sl if (V3PreLex::s_currentLexp->m_parenLevel) appendDefValue(yytext,yyleng); else return (VP_STRING); } + /* Protected blocks */ +"`protected" { yy_push_state(PRTMODE); yymore(); } +<> { linenoInc(); yyerror("EOF in `protected"); yyleng=0; yyterminate(); } +{crnl} { linenoInc(); yymore(); } +. { yymore(); } +"`endprotected" { yy_pop_state(); return (VP_TEXT); } + /* Pass-through include <> filenames */ <> { linenoInc(); yyerror("EOF in unterminated include filename"); yyleng=0; yyterminate(); } {crnl} { linenoInc(); yyerror("Unterminated include filename"); BEGIN(INITIAL); } diff --git a/src/V3PreShell.cpp b/src/V3PreShell.cpp index 00e43ca06..50486c1f3 100644 --- a/src/V3PreShell.cpp +++ b/src/V3PreShell.cpp @@ -61,10 +61,6 @@ protected: s_preprocp->define(prefl,"verilator3", "1"); s_preprocp->define(prefl,"systemc_clock", "/*verilator systemc_clock*/"); s_preprocp->define(prefl,"coverage_block_off", "/*verilator coverage_block_off*/"); - // Standards - We ignore - s_preprocp->define(prefl,"resetall", ""); - s_preprocp->define(prefl,"portcoerce", ""); - s_preprocp->define(prefl,"inline", ""); } } diff --git a/src/verilog.l b/src/verilog.l index 90713d3c6..44cc8ad1d 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -626,18 +626,18 @@ escid \\[^ \t\f\r\n]+ yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); return yaINTNUM; } - [0-9]+[_0-9]*[ \t]*['']s?[bcodhBCODH]?[ \t]*[A-Fa-f0-9xXzZ_?]* { + [0-9][_0-9]*[ \t]*['']s?[bcodhBCODH]?[ \t]*[A-Fa-f0-9xXzZ_?]* { yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); return yaINTNUM; } - [0-9]* { yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); + [0-9][_0-9]* { yylval.nump = V3Read::newNumber(V3Read::fileline(),(char*)yytext); return yaINTNUM; } - [-+]?[0-9]+(\.[0-9]+)([eE][-+]?[0-9]+)? { + [0-9][_0-9]*(\.[0-9]+)([eE][-+]?[0-9]+)? { yylval.cdouble = 0; /* Only for delays, not used yet */ return yaFLOATNUM; } - [-+]?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+) { + [0-9][_0-9]*(\.[0-9]+)?([eE][-+]?[0-9]+) { yylval.cdouble = 0; /* Only for delays, not used yet */ return yaFLOATNUM; } @@ -674,8 +674,13 @@ escid \\[^ \t\f\r\n]+ { "`celldefine" { V3Read::inCellDefine(true); } "`endcelldefine" { V3Read::inCellDefine(false); } + "`endprotect" { } + "`inline" { } "`line"{ws}+[^\n]*\n { V3Read::ppline(yytext); } + "`portcoerce" { } + "`protect" { } "`psl" { if (V3Read::optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } } + "`resetall" { } "`systemc_ctor" { BEGIN SYSCCTOR; } "`systemc_dtor" { BEGIN SYSCDTOR; } "`systemc_header" { BEGIN SYSCHDR; } diff --git a/src/verilog.y b/src/verilog.y index 4aa1e4c07..05e9f1b0c 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -292,7 +292,7 @@ class AstSenTree; %type portV2kDecl ioDecl varDecl %type modParDecl modParList modParE %type modItem modItemList modItemListE modOrGenItem -%type genItem genItemList genItemBegin genItemBlock genTopBlock genCaseList +%type genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList %type dlyTerm %type sigAndAttr sigId sigIdRange sigList regsig regsigList regSigId %type netSig netSigList @@ -310,7 +310,7 @@ class AstSenTree; %type assertStmt %type beginNamed %type caseStmt -%type caseList +%type caseList caseListE %type caseCondList assignList assignOne %type constExpr exprNoStr expr exprPsl exprStrText %type exprList cateList cStrList @@ -537,7 +537,7 @@ genItemList: genItem { $$ = $1; } ; genItem: modOrGenItem { $$ = $1; } - | yCASE '(' expr ')' genCaseList yENDCASE { $$ = new AstGenCase($1,$3,$5); } + | yCASE '(' expr ')' genCaseListE yENDCASE { $$ = new AstGenCase($1,$3,$5); } | yIF expr genItemBlock %prec prLOWER_THAN_ELSE { $$ = new AstGenIf($1,$2,$3,NULL); } | yIF expr genItemBlock yELSE genItemBlock { $$ = new AstGenIf($1,$2,$3,$5); } | yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' genItemBlock @@ -546,6 +546,10 @@ genItem: modOrGenItem { $$ = $1; } ,$13);} ; +genCaseListE: /* empty */ { $$ = NULL; } + | genCaseList { $$ = $1; } + ; + genCaseList: caseCondList ':' genItemBlock { $$ = new AstCaseItem($2,$1,$3); } | yDEFAULT ':' genItemBlock { $$ = new AstCaseItem($2,NULL,$3); } | yDEFAULT genItemBlock { $$ = new AstCaseItem($1,NULL,$2); } @@ -643,9 +647,9 @@ regrangeE: /* empty */ { $$ = NULL; VARRANGE($$); } anyrange: '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; -delayrange: delayE regrangeE { $$ = $2; } - | ySCALARED delayE regrangeE { $$ = $3; } - | yVECTORED delayE regrangeE { $$ = $3; } +delayrange: regrangeE delayE { $$ = $1; } + | ySCALARED regrangeE delayE { $$ = $2; } + | yVECTORED regrangeE delayE { $$ = $2; } ; portRangeE: /* empty */ { $$ = NULL; } @@ -792,7 +796,7 @@ stmt: ';' { $$ = NULL; } //************************************************ // Case/If -stateCaseForIf: caseStmt caseAttrE caseList yENDCASE { $$ = $1; $1->addItemsp($3); } +stateCaseForIf: caseStmt caseAttrE caseListE yENDCASE { $$ = $1; if ($3) $1->addItemsp($3); } | yIF expr stmtBlock %prec prLOWER_THAN_ELSE { $$ = new AstIf($1,$2,$3,NULL); } | yIF expr stmtBlock yELSE stmtBlock { $$ = new AstIf($1,$2,$3,$5); } | yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' stmtBlock @@ -813,6 +817,10 @@ caseAttrE: /*empty*/ { } | caseAttrE yVL_PARALLEL_CASE { V3Parse::s_caseAttrp->parallelPragma(true); } ; +caseListE: /* empty */ { $$ = NULL; } + | caseList { $$ = $1; } + ; + caseList: caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); } | yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($2,NULL,$3); } | yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); } @@ -1053,7 +1061,7 @@ specifyJunk: dlyTerm {} /* ignored */ | '&' {} | '(' {} | ')' {} - | '*' {} | '/' {} | '%' {} | yP_POW {} + | '*' {} | '/' {} | '%' {} | '+' {} | '-' {} | ',' {} | ':' {} @@ -1076,10 +1084,12 @@ specifyJunk: dlyTerm {} /* ignored */ | yP_ANDAND {} | yP_GTE {} | yP_LTE {} | yP_EQUAL {} | yP_NOTEQUAL {} + | yP_CASEEQUAL {} | yP_CASENOTEQUAL {} | yP_XNOR {} | yP_NOR {} | yP_NAND {} | yP_OROR {} | yP_SLEFT {} | yP_SRIGHT {} | yP_SSRIGHT {} | yP_PLUSCOLON {} | yP_MINUSCOLON {} + | yP_POW {} | yP_LOGIF {} | yP_LOGIFF {} diff --git a/test_regress/t/t_case_wild.v b/test_regress/t/t_case_wild.v index 6dd82d997..1dd4eaebd 100644 --- a/test_regress/t/t_case_wild.v +++ b/test_regress/t/t_case_wild.v @@ -60,6 +60,9 @@ module sub (/*AUTOARG*/ output reg [4:0] out2; always @* begin + // Test empty cases + casez (in[0]) + endcase casez (in) 24'b0000_0000_0000_0000_0000_0000 : {out1,out2} = {1'b0,5'h00}; 24'b????_????_????_????_????_???1 : {out1,out2} = {1'b1,5'h00};