From 7f3a73e3142740e9918fa8a27398da2d69486b99 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 22 Aug 2020 22:21:37 -0400 Subject: [PATCH] Fix naming of "id : begin" blocks. --- Changes | 2 + src/V3ParseImp.cpp | 7 ++ src/verilog.y | 103 ++++++++++++------ test_regress/t/t_fork.out | 5 + test_regress/t/t_fork.pl | 9 +- test_regress/t/t_fork.v | 11 +- test_regress/t/t_fork2.out | 5 - .../t/{t_fork2.pl => t_fork_label.pl} | 9 +- test_regress/t/{t_fork2.v => t_fork_label.v} | 19 +++- 9 files changed, 114 insertions(+), 56 deletions(-) create mode 100644 test_regress/t/t_fork.out delete mode 100644 test_regress/t/t_fork2.out rename test_regress/t/{t_fork2.pl => t_fork_label.pl} (82%) rename test_regress/t/{t_fork2.v => t_fork_label.v} (55%) diff --git a/Changes b/Changes index 40003440a..309dce172 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix false DECLFILENAME on black-boxed modules (#2430). [Philipp Wagner] +**** Fix naming of "id : begin" blocks. + * Verilator 4.040 2020-08-15 diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index bf8867daf..c4b1766a4 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -382,6 +382,7 @@ void V3ParseImp::tokenPipeline() { int token = yylval.token; // If a paren, read another if (token == '(' // + || token == ':' // || token == yCONST__LEX // || token == yGLOBAL__LEX // || token == yLOCAL__LEX // @@ -402,6 +403,12 @@ void V3ParseImp::tokenPipeline() { if (token == '(' && (nexttok == ygenSTRENGTH || nexttok == ySUPPLY0 || nexttok == ySUPPLY1)) { token = yP_PAR__STRENGTH; + } else if (token == ':') { + if (nexttok == yBEGIN) { + token = yP_COLON__BEGIN; + } else if (nexttok == yFORK) { + token = yP_COLON__FORK; + } } else if (token == yCONST__LEX) { if (nexttok == yREF) { token = yCONST__REF; diff --git a/src/verilog.y b/src/verilog.y index 375ae85a2..1692b3059 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -398,7 +398,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token '#' %token '%' %token '&' -%token '(' +%token '(' // See also yP_PAR__STRENGTH %token ')' %token '*' %token '+' @@ -406,7 +406,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token '-' %token '.' %token '/' -%token ':' +%token ':' // See also yP_COLON__BEGIN or yP_COLON__FORK %token ';' %token '<' %token '=' @@ -840,6 +840,8 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yP_SSRIGHT ">>>" %token yP_POW "**" +%token yP_COLON__BEGIN ":-begin" +%token yP_COLON__FORK ":-fork" //UNSUP %token yP_PAR__IGNORE "(-ignored" // Used when sequence_expr:expr:( is ignored %token yP_PAR__STRENGTH "(-for-strength" @@ -926,7 +928,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) // Verilog op precedence %right yP_MINUSGT yP_LTMINUSGT -%right '?' ':' +%right '?' ':' yP_COLON__BEGIN yP_COLON__FORK %left yP_OROR %left yP_ANDAND %left '|' yP_NOR @@ -2339,9 +2341,10 @@ generate_block_or_null: // IEEE: generate_block_or_null (called from genc genItemBegin: // IEEE: part of generate_block yBEGIN ~c~genItemList yEND { $$ = new AstBegin($1,"",$2,true,false); } | yBEGIN yEND { $$ = nullptr; } - | id ':' yBEGIN ~c~genItemList yEND endLabelE + | id yP_COLON__BEGIN yBEGIN ~c~genItemList yEND endLabelE { $$ = new AstBegin($1,*$1,$4,true,false); GRAMMARP->endLabel($6,*$1,$6); } - | id ':' yBEGIN yEND endLabelE { $$ = nullptr; GRAMMARP->endLabel($5,*$1,$5); } + | id yP_COLON__BEGIN yBEGIN yEND endLabelE + { $$ = nullptr; GRAMMARP->endLabel($5,*$1,$5); } | yBEGIN ':' idAny ~c~genItemList yEND endLabelE { $$ = new AstBegin($3,*$3,$4,true,false); GRAMMARP->endLabel($6,*$3,$6); } | yBEGIN ':' idAny yEND endLabelE { $$ = nullptr; GRAMMARP->endLabel($5,*$3,$5); } @@ -2466,8 +2469,8 @@ case_generate_itemList: // IEEE: { case_generate_itemList } //UNSUP ; case_generate_item: // ==IEEE: case_generate_item - caseCondList ':' generate_block_or_null { $$ = new AstCaseItem($2,$1,$3); } - | yDEFAULT ':' generate_block_or_null { $$ = new AstCaseItem($1,nullptr,$3); } + caseCondList colon generate_block_or_null { $$ = new AstCaseItem($2,$1,$3); } + | yDEFAULT colon generate_block_or_null { $$ = new AstCaseItem($1,nullptr,$3); } | yDEFAULT generate_block_or_null { $$ = new AstCaseItem($1,nullptr,$2); } ; @@ -2878,35 +2881,45 @@ stmtBlock: // IEEE: statement + seq_block + par_block seq_block: // ==IEEE: seq_block // // IEEE doesn't allow declarations in unnamed blocks, but several simulators do. // // So need AstBegin's even if unnamed to scope variables down - seq_blockFront blockDeclStmtList yEND endLabelE { $$=$1; $1->addStmtsp($2); SYMP->popScope($1); GRAMMARP->endLabel($4,$1,$4); } - | seq_blockFront /**/ yEND endLabelE { $$=$1; SYMP->popScope($1); GRAMMARP->endLabel($3,$1,$3); } + seq_blockFront blockDeclStmtListE yEND endLabelE + { $$ = $1; $1->addStmtsp($2); + SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } + ; + +seq_blockPreId: // IEEE: seq_block, but called with leading ID + seq_blockFrontPreId blockDeclStmtListE yEND endLabelE + { $$ = $1; $1->addStmtsp($2); + SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } ; par_block: // ==IEEE: par_block - par_blockFront blockDeclStmtList yJOIN endLabelE + par_blockFront blockDeclStmtListE yJOIN endLabelE { $$ = $1; $1->addStmtsp($2); $1->joinType(VJoinType::JOIN); SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } - | par_blockFront /**/ yJOIN endLabelE - { $$ = $1; + | par_blockFront blockDeclStmtListE yJOIN_ANY endLabelE + { $$ = $1; $1->addStmtsp($2); + $1->joinType(VJoinType::JOIN_ANY); + SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } + | par_blockFront blockDeclStmtListE yJOIN_NONE endLabelE + { $$ = $1; $1->addStmtsp($2); + $1->joinType(VJoinType::JOIN_NONE); + SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } + ; + +par_blockPreId: // ==IEEE: par_block but called with leading ID + par_blockFrontPreId blockDeclStmtListE yJOIN endLabelE + { $$ = $1; $1->addStmtsp($2); $1->joinType(VJoinType::JOIN); - SYMP->popScope($1); GRAMMARP->endLabel($3, $1, $3); } - | par_blockFront blockDeclStmtList yJOIN_ANY endLabelE + SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } + | par_blockFrontPreId blockDeclStmtListE yJOIN_ANY endLabelE { $$ = $1; $1->addStmtsp($2); $1->joinType(VJoinType::JOIN_ANY); SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } - | par_blockFront /**/ yJOIN_ANY endLabelE - { $$ = $1; - $1->joinType(VJoinType::JOIN_ANY); - SYMP->popScope($1); GRAMMARP->endLabel($3, $1, $3); } - | par_blockFront blockDeclStmtList yJOIN_NONE endLabelE + | par_blockFrontPreId blockDeclStmtListE yJOIN_NONE endLabelE { $$ = $1; $1->addStmtsp($2); $1->joinType(VJoinType::JOIN_NONE); SYMP->popScope($1); GRAMMARP->endLabel($4, $1, $4); } - | par_blockFront /**/ yJOIN_NONE endLabelE - { $$ = $1; - $1->joinType(VJoinType::JOIN_NONE); - SYMP->popScope($1); GRAMMARP->endLabel($3, $1, $3); } ; seq_blockFront: // IEEE: part of seq_block @@ -2919,6 +2932,17 @@ par_blockFront: // IEEE: part of par_block | yFORK ':' idAny/*new-block_identifier*/ { $$ = new AstFork($3, *$3, nullptr); SYMP->pushNew($$); } ; +seq_blockFrontPreId: // IEEE: part of seq_block/stmt with leading id + id/*block_identifier*/ yP_COLON__BEGIN yBEGIN + { $$ = new AstBegin($3, *$1, nullptr); SYMP->pushNew($$); } + ; + +par_blockFrontPreId: // IEEE: part of par_block/stmt with leading id + id/*block_identifier*/ yP_COLON__FORK yFORK + { $$ = new AstFork($3, *$1, nullptr); SYMP->pushNew($$); } + ; + + blockDeclStmtList: // IEEE: { block_item_declaration } { statement or null } // // The spec seems to suggest a empty declaration isn't ok, but most simulators take it block_item_declarationList { $$ = $1; } @@ -2926,6 +2950,11 @@ blockDeclStmtList: // IEEE: { block_item_declaration } { statement or nul | stmtList { $$ = $1; } ; +blockDeclStmtListE: // IEEE: [ { block_item_declaration } { statement or null } ] + /*empty*/ { $$ = nullptr; } + | blockDeclStmtList { $$ = $1; } + ; + block_item_declarationList: // IEEE: [ block_item_declaration ] block_item_declaration { $$ = $1; } | block_item_declarationList block_item_declaration { $$ = $1->addNextNull($2); } @@ -2948,6 +2977,9 @@ stmt: // IEEE: statement_or_null == function_statement_or_null | id/*block_identifier*/ ':' statement_item { $$ = new AstBegin($1, *$1, $3); } // // from _or_null | ';' { $$ = nullptr; } + // // labeled par_block/seq_block with leading ':' + | seq_blockPreId { $$ = $1; } + | par_blockPreId { $$ = $1; } ; statement_item: // IEEE: statement_item @@ -3227,21 +3259,21 @@ case_insideListE: // IEEE: [ { case_inside_item } ] ; case_itemList: // IEEE: { case_item + ... } - caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); } - | yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($1,nullptr,$3); } + caseCondList colon stmtBlock { $$ = new AstCaseItem($2,$1,$3); } + | yDEFAULT colon stmtBlock { $$ = new AstCaseItem($1,nullptr,$3); } | yDEFAULT stmtBlock { $$ = new AstCaseItem($1,nullptr,$2); } - | case_itemList caseCondList ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } + | case_itemList caseCondList colon stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } | case_itemList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,nullptr,$3)); } - | case_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,nullptr,$4)); } + | case_itemList yDEFAULT colon stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,nullptr,$4)); } ; case_inside_itemList: // IEEE: { case_inside_item + open_range_list ... } - open_range_list ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); } - | yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($1,nullptr,$3); } + open_range_list colon stmtBlock { $$ = new AstCaseItem($2,$1,$3); } + | yDEFAULT colon stmtBlock { $$ = new AstCaseItem($1,nullptr,$3); } | yDEFAULT stmtBlock { $$ = new AstCaseItem($1,nullptr,$2); } - | case_inside_itemList open_range_list ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } + | case_inside_itemList open_range_list colon stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); } | case_inside_itemList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,nullptr,$3)); } - | case_inside_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,nullptr,$4)); } + | case_inside_itemList yDEFAULT colon stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,nullptr,$4)); } ; open_range_list: // ==IEEE: open_range_list + open_value_range @@ -6160,6 +6192,15 @@ timeNumAdjusted: // Time constant, adjusted to module's time units/preci { $$ = new AstTimeImport($1, new AstConst($1, AstConst::RealDouble(), $1)); } ; +//********************************************************************** +// Generic tokens + +colon: // Generic colon that isn't making a label (e.g. in a case_item) + ':' { $$ = $1; } + | yP_COLON__BEGIN { $$ = $1; } + | yP_COLON__FORK { $$ = $1; } + ; + //********************************************************************** // VLT Files diff --git a/test_regress/t/t_fork.out b/test_regress/t/t_fork.out new file mode 100644 index 000000000..03e479d9f --- /dev/null +++ b/test_regress/t/t_fork.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_fork.v:10:14: Unsupported: fork statements + : ... In instance t + 10 | fork : fblk + | ^~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_fork.pl b/test_regress/t/t_fork.pl index 1c4ba9485..a5846c699 100755 --- a/test_regress/t/t_fork.pl +++ b/test_regress/t/t_fork.pl @@ -8,11 +8,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(simulator => 1); +scenarios(vlt => 1); -compile(); - -execute(); +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); ok(1); 1; diff --git a/test_regress/t/t_fork.v b/test_regress/t/t_fork.v index b92cf8830..33eb0b485 100644 --- a/test_regress/t/t_fork.v +++ b/test_regress/t/t_fork.v @@ -7,15 +7,10 @@ module t (/*AUTOARG*/); initial begin - // With no statements this is a NOP - fork - join - fork - join_any - fork - join_none - // With one statement this is supported and optimized to a begin/end fork : fblk + begin + $write("Forked"); + end begin $write("*-* All Finished *-*\n"); $finish; diff --git a/test_regress/t/t_fork2.out b/test_regress/t/t_fork2.out deleted file mode 100644 index e72b77c58..000000000 --- a/test_regress/t/t_fork2.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error-UNSUPPORTED: t/t_fork2.v:10:14: Unsupported: fork statements - : ... In instance t - 10 | fork : fblk - | ^~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_fork2.pl b/test_regress/t/t_fork_label.pl similarity index 82% rename from test_regress/t/t_fork2.pl rename to test_regress/t/t_fork_label.pl index a5846c699..1c4ba9485 100755 --- a/test_regress/t/t_fork2.pl +++ b/test_regress/t/t_fork_label.pl @@ -8,12 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 -scenarios(vlt => 1); +scenarios(simulator => 1); -lint( - fails => 1, - expect_filename => $Self->{golden_filename}, - ); +compile(); + +execute(); ok(1); 1; diff --git a/test_regress/t/t_fork2.v b/test_regress/t/t_fork_label.v similarity index 55% rename from test_regress/t/t_fork2.v rename to test_regress/t/t_fork_label.v index 33eb0b485..a5d6112da 100644 --- a/test_regress/t/t_fork2.v +++ b/test_regress/t/t_fork_label.v @@ -7,10 +7,23 @@ module t (/*AUTOARG*/); initial begin + // Label checks + begin : b1 + end : b1 + // + b2 : begin + end : b2 + // With no statements this is a NOP + fork : f1 + join : f1 + // + f2: fork + join_any : f2 + // + fork + join_none + // With one statement this is supported and optimized to a begin/end fork : fblk - begin - $write("Forked"); - end begin $write("*-* All Finished *-*\n"); $finish;