From 3a0b8c88700ecfb083026908d2b28bddf1884f91 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 6 Jun 2020 13:43:59 -0400 Subject: [PATCH] Fix parsing parameter type with assignment and no type keyword. --- src/verilog.y | 17 +++++++++++++++-- test_regress/t/t_param_type.v | 15 ++++++++------- test_regress/t/t_param_type_bad2.out | 10 ++++++---- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index 721d60942..3e4944bdf 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2569,8 +2569,15 @@ packed_dimension: // ==IEEE: packed_dimension param_assignment: // ==IEEE: param_assignment // // IEEE: constant_param_expression // // constant_param_expression: '$' is in expr - id/*new-parameter*/ variable_dimensionListE sigAttrListE exprEqE - { $$ = VARDONEA($1, *$1, $2, $3); if ($4) $$->valuep($4); } + id/*new-parameter*/ variable_dimensionListE sigAttrListE exprOrDataTypeEqE + { // To handle #(type A=int, B=A) and properly imply B + // as a type (for parsing) we need to detect "A" is a type + if (AstNodeDType* refp = VN_CAST($4, NodeDType)) { + if (VSymEnt* foundp = SYMP->symCurrentp()->findIdFallback(refp->name())) { + UINFO(9, "declaring type via param assignment" << foundp->nodep() << endl); + VARDTYPE(new AstParseTypeDType($1)) + SYMP->reinsert(foundp->nodep()->cloneTree(false), NULL, *$1); }} + $$ = VARDONEA($1, *$1, $2, $3); if ($4) $$->valuep($4); } ; list_of_param_assignments: // ==IEEE: list_of_param_assignments @@ -3925,6 +3932,12 @@ exprEqE: // IEEE: optional '=' expression (part of param_assignment) | '=' expr { $$ = $2; } ; +exprOrDataTypeEqE: // IEEE: optional '=' expression (part of param_assignment) + // // constant_param_expression: '$' is in expr + /*empty*/ { $$ = NULL; } + | '=' exprOrDataType { $$ = $2; } + ; + constExpr: expr { $$ = $1; } ; diff --git a/test_regress/t/t_param_type.v b/test_regress/t/t_param_type.v index a61fb1b77..9fbeaa969 100644 --- a/test_regress/t/t_param_type.v +++ b/test_regress/t/t_param_type.v @@ -73,13 +73,14 @@ module mod_typ #( endmodule -module mod_typ2 #( - parameter int WIDTH1 = 0, - parameter int WIDTH2 = WIDTH1, - parameter type TYP1 = byte, - //UNSUP not needing 'parameter type' below and implying it - parameter type TYP2 = TYP1 - )(); +module mod_typ2 + #( + parameter int WIDTH1 = 0, + parameter int WIDTH2 = WIDTH1, + parameter type TYP1 = byte, + // Below we need to imply that TYP2 is a type + TYP2 = TYP1 + )(); TYP1 t1; TYP2 t2; diff --git a/test_regress/t/t_param_type_bad2.out b/test_regress/t/t_param_type_bad2.out index 381c74e76..9d199c249 100644 --- a/test_regress/t/t_param_type_bad2.out +++ b/test_regress/t/t_param_type_bad2.out @@ -1,7 +1,9 @@ -%Error: t/t_param_type_bad2.v:8:24: syntax error, unexpected ';', expecting "'{" +%Error: t/t_param_type_bad2.v:8:19: Operator VAR 't' expected non-datatype Initial value but 'logic' is a datatype. + : ... In instance t 8 | localparam t = logic; - | ^ -%Error: t/t_param_type_bad2.v:9:28: syntax error, unexpected ';', expecting "'{" + | ^~~~~ +%Error: t/t_param_type_bad2.v:9:20: Operator VAR 't2' expected non-datatype Initial value but 'real' is a datatype. + : ... In instance t 9 | localparam t2 = realtime; - | ^ + | ^~~~~~~~ %Error: Exiting due to