From 97b21b3849ea84dfac3fa5a5cd96867ed3c30eeb Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 2 Mar 2024 09:06:54 -0500 Subject: [PATCH] Parse 1800-2023 --- Changes | 2 +- src/verilog.l | 6 + src/verilog.y | 240 +++++++++++++++++++------ test_regress/t/t_assoc_method.v | 2 +- test_regress/t/t_bitsel_concat.pl | 21 +++ test_regress/t/t_bitsel_concat.v | 91 ++++++++++ test_regress/t/t_class_new_default.out | 11 ++ test_regress/t/t_class_new_default.pl | 19 ++ test_regress/t/t_class_new_default.v | 28 +++ test_regress/t/t_covergroup_unsup.out | 3 + test_regress/t/t_covergroup_unsup.v | 3 + test_regress/t/t_param_type_fwd.out | 32 ++++ test_regress/t/t_param_type_fwd.pl | 19 ++ test_regress/t/t_param_type_fwd.v | 26 +++ test_regress/t/t_union_soft.out | 5 + test_regress/t/t_union_soft.pl | 19 ++ test_regress/t/t_union_soft.v | 25 +++ test_regress/t/t_var_ref_static.out | 8 + test_regress/t/t_var_ref_static.pl | 19 ++ test_regress/t/t_var_ref_static.v | 16 ++ 20 files changed, 542 insertions(+), 53 deletions(-) create mode 100755 test_regress/t/t_bitsel_concat.pl create mode 100644 test_regress/t/t_bitsel_concat.v create mode 100644 test_regress/t/t_class_new_default.out create mode 100755 test_regress/t/t_class_new_default.pl create mode 100644 test_regress/t/t_class_new_default.v create mode 100644 test_regress/t/t_param_type_fwd.out create mode 100755 test_regress/t/t_param_type_fwd.pl create mode 100644 test_regress/t/t_param_type_fwd.v create mode 100644 test_regress/t/t_union_soft.out create mode 100755 test_regress/t/t_union_soft.pl create mode 100644 test_regress/t/t_union_soft.v create mode 100644 test_regress/t/t_var_ref_static.out create mode 100755 test_regress/t/t_var_ref_static.pl create mode 100644 test_regress/t/t_var_ref_static.v diff --git a/Changes b/Changes index fd5001c94..98082a712 100644 --- a/Changes +++ b/Changes @@ -13,7 +13,7 @@ Verilator 5.023 devel **Major:** -* Support 1800-2023 keywords. +* Support 1800-2023 keywords, and parsing with UNDEFINED warnings. * Support 1800-2023 preprocessor ifdef expressions. * Support 1800-2023 DPI headers, svGetTime/svgGetTimeUnit/svGetTimePrecision methods. diff --git a/src/verilog.l b/src/verilog.l index 5e9c82281..2087ec548 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -896,6 +896,12 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "<->" { FL; return yP_LTMINUSGT; } } + /* SystemVerilog 2023 Operators */ +{ + "+/-" { FL; return yP_PLUSSLASHMINUS; } + "+%-" { FL; return yP_PLUSPCTMINUS; } +} + /* Identifiers and numbers */ { {escid} { FL; yylval.strp = PARSEP->newString diff --git a/src/verilog.y b/src/verilog.y index ce84f4f3f..813f9e449 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1055,6 +1055,9 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yP_SRIGHTEQ ">>=" %token yP_SSRIGHTEQ ">>>=" +%token yP_PLUSSLASHMINUS "+/-" +%token yP_PLUSPCTMINUS "+%-" + // [* is not an operator, as "[ * ]" is legal // [= and [-> could be repetition operators, but to match [* we don't add them. // '( is not an operator, as "' (" is legal @@ -1276,6 +1279,8 @@ package_or_generate_item_declaration: // ==IEEE: package_or_generate_i | dpi_import_export { $$ = $1; } | extern_constraint_declaration { $$ = $1; } | class_declaration { $$ = $1; } + // // IEEE-2023: Added: interface_class_declaration + // // interface_class_declaration is part of class_declaration // // class_constructor_declaration is part of function_declaration // // local_parameter_declaration under parameter_declaration | parameter_declaration ';' { $$ = $1; } @@ -1700,6 +1705,8 @@ anonymous_program_item: // ==IEEE: anonymous_program_item task_declaration { $$ = $1; } | function_declaration { $$ = $1; } | class_declaration { $$ = $1; } + // // IEEE-2023: Added: interface_class_declaration + // // interface_class_declaration is part of class_declaration | covergroup_declaration { $$ = $1; } // // class_constructor_declaration is part of function_declaration | ';' { $$ = nullptr; } @@ -1855,7 +1862,7 @@ genvar_identifierDecl: // IEEE: genvar_identifier (for declarat $$ = VARDONEA($1, *$1, nullptr, $2); } ; -parameter_declaration: // IEEE: local_ or parameter_declaration +parameter_declaration: // IEEE: local_ or parameter_declaration and type_parameter_declaration // // IEEE: yPARAMETER yTYPE list_of_type_assignments ';' // // Instead of list_of_type_assignments // // we use list_of_param_assignments because for port handling @@ -1874,6 +1881,8 @@ parameter_declarationFront: // IEEE: local_ or parameter_declaration w/o ass parameter_declarationTypeFront: // IEEE: local_ or parameter_declaration w/o assignment // // Front must execute first so VARDTYPE is ready before list of vars varParamReset yTYPE__ETC { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType{$2}); } + | varParamReset yTYPE__ETC forward_type { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType{$2}); + BBUNSUP($1, "Unsupported: 'parameter type' forward type"); } ; parameter_port_declarationFrontE: // IEEE: local_ or parameter_port_declaration w/o assignment @@ -1895,7 +1904,19 @@ parameter_port_declarationTypeFrontE: // IEEE: parameter_port_declaration w/o as // // IEEE: local_parameter_declaration (minus assignment) // // Front must execute first so VARDTYPE is ready before list of vars varParamReset yTYPE__ETC { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType{$2}); } + | varParamReset yTYPE__ETC forward_type { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType{$2}); + BBUNSUP($1, "Unsupported: 'parameter type' forward type"); } | yTYPE__ETC { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType{$1}); } + | yTYPE__ETC forward_type { /*VARRESET-in-varParam*/ VARDTYPE(new AstParseTypeDType{$1}); + BBUNSUP($1, "Unsupported: 'parameter type' forward type"); } + ; + +forward_type: // ==IEEE: forward_type + yENUM { } + | ySTRUCT { } + | yUNION { } + | yCLASS { } + | yINTERFACE yCLASS { } ; net_declaration: // IEEE: net_declaration - excluding implict @@ -1975,7 +1996,12 @@ port_direction: // ==IEEE: port_direction + tf_port_direction | yOUTPUT { VARIO(OUTPUT); } | yINOUT { VARIO(INOUT); } | yREF { VARIO(REF); } + // // IEEE 1800-2023: Added 'ref static' and 'const ref static' + | yREF ySTATIC__ETC { VARIO(REF); + BBUNSUP($1, "Unsupported: 'ref static' ports"); } | yCONST__REF yREF { VARIO(CONSTREF); } + | yCONST__REF yREF ySTATIC__ETC { VARIO(CONSTREF); + BBUNSUP($1, "Unsupported: 'ref static' ports"); } ; port_directionReset: // IEEE: port_direction that starts a port_declaraiton @@ -2083,6 +2109,8 @@ simple_type: // ==IEEE: simple_type ; data_type: // ==IEEE: data_type + // // IEEE: data_type_or_incomplete_class_scoped_type parses same as this + // // as can't tell them apart until link // // This expansion also replicated elsewhere, IE data_type__AndID data_typeNoRef { $$ = $1; } // @@ -2188,7 +2216,7 @@ struct_unionDecl: // IEEE: part of data_type /*mid*/ { $$ = new AstStructDType{$1, $2}; SYMP->pushNew($$); } /*cont*/ struct_union_memberList '}' { $$ = $4; $$->addMembersp($5); SYMP->popScope($$); } - | yUNION taggedE packedSigningE '{' + | yUNION taggedSoftE packedSigningE '{' /*mid*/ { $$ = new AstUnionDType{$1, $3}; SYMP->pushNew($$); } /*cont*/ struct_union_memberList '}' { $$ = $5; $$->addMembersp($6); SYMP->popScope($$); } @@ -2325,8 +2353,9 @@ random_qualifier: // ==IEEE: random_qualifier | yRANDC { $$ = VMemberQualifiers::none(); $$.m_randc = true; } ; -taggedE: +taggedSoftE: /*empty*/ { } + | ySOFT { BBUNSUP($1, "Unsupported: 'union soft'"); } //UNSUP yTAGGED { UNSUP } ; @@ -2568,6 +2597,7 @@ type_declaration: // ==IEEE: type_declaration // // Verilator: Not important what it is in the AST, just need // // to make sure the yaID__aTYPE gets returned | yTYPEDEF id ';' { $$ = GRAMMARP->createTypedefFwd($2, *$2); } + // // IEEE: expanded forward_type to prevent conflict | yTYPEDEF yENUM idAny ';' { $$ = GRAMMARP->createTypedefFwd($3, *$3); } | yTYPEDEF ySTRUCT idAny ';' { $$ = GRAMMARP->createTypedefFwd($3, *$3); } | yTYPEDEF yUNION idAny ';' { $$ = GRAMMARP->createTypedefFwd($3, *$3); } @@ -3326,9 +3356,11 @@ attr_event_control: // ==IEEE: event_control ; event_control: // ==IEEE: event_control - '@' '(' event_expression ')' { $$ = new AstSenTree{$1, $3}; } - | '@' '(' '*' ')' { $$ = nullptr; } + // UNSUP: Needs alignment with IEEE event_control and clocking_event + '@' '(' '*' ')' { $$ = nullptr; } | '@' '*' { $$ = nullptr; } + // // IEEE: clocking_event + | '@' '(' event_expression ')' { $$ = new AstSenTree{$1, $3}; } // // IEEE: hierarchical_event_identifier // // UNSUP below should be idClassSel | '@' senitemVar { $$ = new AstSenTree{$1, $2}; } /* For events only */ @@ -3505,6 +3537,8 @@ statement_item: // IEEE: statement_item // // This is ignored to avoid conflicts | fexprLvalue '=' class_new ';' { $$ = new AstAssign{$2, $1, $3}; } | fexprLvalue '=' dynamic_array_new ';' { $$ = new AstAssign{$2, $1, $3}; } + // // IEEE: inc_or_dec_expression + | finc_or_dec_expression ';' { $$ = $1; } // // // IEEE: nonblocking_assignment | fexprLvalue yP_LTE delay_or_event_controlE expr ';' @@ -3553,9 +3587,6 @@ statement_item: // IEEE: statement_item if ($1 == uniq_UNIQUE0) newp->unique0Pragma(true); if ($1 == uniq_PRIORITY) newp->priorityPragma(true); } // - // // IEEE: inc_or_dec_expression - | finc_or_dec_expression ';' { $$ = $1; } - // // // IEEE: subroutine_call_statement // // IEEE says we then expect a function call // // (function_subroutine_callNoMethod), but rest of @@ -3834,12 +3865,30 @@ range_list: // ==IEEE: range_list/open_range_list + value_range/o value_range: // ==IEEE: value_range/open_value_range expr { $$ = $1; } | '[' expr ':' expr ']' { $$ = new AstInsideRange{$1, $2, $4}; } + // // IEEE-2023: added all four: + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' '$' ':' expr ']' + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' expr ':' '$' ']' + | '[' expr yP_PLUSSLASHMINUS expr ']' + { $$ = nullptr; BBUNSUP($1, "Unsupported: +/- range"); } + | '[' expr yP_PLUSPCTMINUS expr ']' + { $$ = nullptr; BBUNSUP($1, "Unsupported: +%- range"); } ; covergroup_value_range: // ==IEEE-2012: covergroup_value_range cgexpr { $$ = $1; } | '[' cgexpr ':' cgexpr ']' { $$ = nullptr; BBUNSUP($1, "Unsupported: covergroup value range"); } + // // IEEE-2023: added all four: + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' '$' ':' cgexpr ']' + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' cgexpr ':' '$' ']' + | '[' cgexpr yP_PLUSSLASHMINUS cgexpr ']' + { $$ = nullptr; BBUNSUP($1, "Unsupported: covergroup value range"); } + | '[' cgexpr yP_PLUSPCTMINUS cgexpr ']' + { $$ = nullptr; BBUNSUP($1, "Unsupported: covergroup value range"); } ; caseCondList: // IEEE: part of case_item @@ -4395,44 +4444,46 @@ list_of_argumentsE: // IEEE: [list_of_arguments] ; task_declaration: // ==IEEE: task_declaration - yTASK lifetimeE taskId tfGuts yENDTASK endLabelE - { $$ = $3; $$->addStmtsp($4); SYMP->popScope($$); - $$->lifetime($2); - GRAMMARP->endLabel($6, $$, $6); } + yTASK dynamic_override_specifiersE lifetimeE taskId tfGuts yENDTASK endLabelE + { $$ = $4; $$->addStmtsp($5); SYMP->popScope($$); + $$->lifetime($3); + GRAMMARP->endLabel($7, $$, $7); } ; task_prototype: // ==IEEE: task_prototype - yTASK taskId '(' tf_port_listE ')' - { $$ = $2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); } - | yTASK taskId - { $$ = $2; $$->prototype(true); SYMP->popScope($$); } + yTASK dynamic_override_specifiersE taskId '(' tf_port_listE ')' + { $$ = $3; $$->addStmtsp($5); $$->prototype(true); SYMP->popScope($$); } + | yTASK dynamic_override_specifiersE taskId + { $$ = $3; $$->prototype(true); SYMP->popScope($$); } ; function_declaration: // IEEE: function_declaration + function_body_declaration - yFUNCTION lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE - { $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5); - $$->lifetime($2); + yFUNCTION dynamic_override_specifiersE lifetimeE funcId funcIsolateE tfGuts yENDFUNCTION endLabelE + { $$ = $4; $4->attrIsolateAssign($5); $$->addStmtsp($6); + $$->lifetime($3); SYMP->popScope($$); - GRAMMARP->endLabel($7, $$, $7); } - | yFUNCTION lifetimeE funcIdNew funcIsolateE tfGuts yENDFUNCTION endLabelE - { $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5); - $$->lifetime($2); + GRAMMARP->endLabel($8, $$, $8); } + | yFUNCTION dynamic_override_specifiersE lifetimeE funcIdNew funcIsolateE tfNewGuts yENDFUNCTION endLabelE + { $$ = $4; $4->attrIsolateAssign($5); $$->addStmtsp($6); + $$->lifetime($3); SYMP->popScope($$); - GRAMMARP->endLabel($7, $$, $7); } + GRAMMARP->endLabel($8, $$, $8); } ; function_prototype: // IEEE: function_prototype - yFUNCTION funcId '(' tf_port_listE ')' - { $$ = $2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); } - | yFUNCTION funcId - { $$ = $2; $$->prototype(true); SYMP->popScope($$); } + yFUNCTION dynamic_override_specifiersE funcId '(' tf_port_listE ')' + { $$ = $3; $$->addStmtsp($5); $$->prototype(true); SYMP->popScope($$); } + | yFUNCTION dynamic_override_specifiersE funcId + { $$ = $3; $$->prototype(true); SYMP->popScope($$); } ; class_constructor_prototype: // ==IEEE: class_constructor_prototype - yFUNCTION funcIdNew '(' tf_port_listE ')' ';' - { $$ = $2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); } - | yFUNCTION funcIdNew ';' - { $$ = $2; $$->prototype(true); SYMP->popScope($$); } + // // IEEE has no dynamic_override_specifiersE, + // // but required to avoid conflicts, so we must check after parsing + yFUNCTION dynamic_override_specifiersE funcIdNew '(' class_constructor_arg_listE ')' ';' + { $$ = $3; $$->addStmtsp($5); $$->prototype(true); SYMP->popScope($$); } + | yFUNCTION dynamic_override_specifiersE funcIdNew ';' + { $$ = $3; $$->prototype(true); SYMP->popScope($$); } ; funcIsolateE: @@ -4538,6 +4589,11 @@ tfGuts: | ';' tfBodyE { $$ = $2; } ; +tfNewGuts: + '(' class_constructor_arg_listE ')' ';' tfBodyE { $$ = addNextNull($2, $5); } + | ';' tfBodyE { $$ = $2; } + ; + tfBodyE: // IEEE: part of function_body_declaration/task_body_declaration /* empty */ { $$ = nullptr; } | tf_item_declarationList { $$ = $1; } @@ -4573,6 +4629,22 @@ tf_port_listList: // IEEE: part of tf_port_list | tf_port_listList ',' tf_port_item { $$ = addNextNull($1, $3); } ; +class_constructor_arg_listE: // IEEE: class_constructor_arg_list or empty + /*empty*/ + /*mid*/ { VARRESET_LIST(UNKNOWN); VARIO(INPUT); } + /*cont*/ class_constructor_arg_listList { $$ = $2; VARRESET_NONLIST(UNKNOWN); } + ; + +class_constructor_arg_listList: // IEEE: part of class_constructor_arg_list + class_constructor_arg { $$ = $1; } + | class_constructor_arg_listList ',' class_constructor_arg { $$ = addNextNull($1, $3); } + ; + +class_constructor_arg: // ==IEEE: class_constructor_arg + tf_port_item { $$ = $1; } + | yDEFAULT { $$ = nullptr; BBUNSUP($1, "Unsupported: new constructor 'default' argument"); } + ; + tf_port_item: // ==IEEE: tf_port_item // // We split tf_port_item into the type and assignment as don't know what follows a comma /* empty */ { $$ = nullptr; PINNUMINC(); } // For example a ",," port @@ -4830,7 +4902,7 @@ expr: // IEEE: part of expression/constant_expression/ // // // IEEE: tagged_union_expression //UNSUP yTAGGED id/*member*/ %prec prTAGGED { UNSUP } - //UNSUP yTAGGED id/*member*/ %prec prTAGGED expr { UNSUP } + //UNSUP yTAGGED id/*member*/ %prec prTAGGED primary { UNSUP } // //======================// IEEE: primary/constant_primary // @@ -4850,14 +4922,50 @@ expr: // IEEE: part of expression/constant_expression/ // // Part of exprOkLvalue below // // // IEEE: multiple_concatenation/constant_multiple_concatenation - | '{' constExpr '{' cateList '}' '}' { $$ = new AstReplicate{$3, $4, $2}; } + | '{' constExpr '{' cateList '}' '}' + { $$ = new AstReplicate{$3, $4, $2}; } + | '{' constExpr '{' cateList '}' '}' '[' expr ']' + { $$ = new AstSelBit{$7, new AstReplicate{$3, $4, $2}, $8}; } + | '{' constExpr '{' cateList '}' '}' '[' constExpr ':' constExpr ']' + { $$ = new AstSelExtract{$7, new AstReplicate{$3, $4, $2}, $8, $10}; } + | '{' constExpr '{' cateList '}' '}' '[' expr yP_PLUSCOLON constExpr ']' + { $$ = new AstSelPlus{$7, new AstReplicate{$3, $4, $2}, $8, $10}; } + | '{' constExpr '{' cateList '}' '}' '[' expr yP_MINUSCOLON constExpr ']' + { $$ = new AstSelMinus{$7, new AstReplicate{$3, $4, $2}, $8, $10}; } // // UNSUP some other rules above // - | function_subroutine_callNoMethod { $$ = $1; } + | function_subroutine_callNoMethod + { $$ = $1; } + | function_subroutine_callNoMethod '[' expr ']' + { $$ = new AstSelBit{$2, $1, $3}; } + | function_subroutine_callNoMethod '[' constExpr ':' constExpr ']' + { $$ = new AstSelExtract{$2, $1, $3, $5}; } + | function_subroutine_callNoMethod '[' expr yP_PLUSCOLON constExpr ']' + { $$ = new AstSelPlus{$2, $1, $3, $5}; } + | function_subroutine_callNoMethod '[' expr yP_MINUSCOLON constExpr ']' + { $$ = new AstSelMinus{$2, $1, $3, $5}; } // // method_call - | ~l~expr '.' function_subroutine_callNoMethod { $$ = new AstDot{$2, false, $1, $3}; } + | ~l~expr '.' function_subroutine_callNoMethod + { $$ = new AstDot{$2, false, $1, $3}; } + | ~l~expr '.' function_subroutine_callNoMethod '[' expr ']' + { $$ = new AstSelBit{$4, new AstDot{$2, false, $1, $3}, $5}; } + | ~l~expr '.' function_subroutine_callNoMethod '[' constExpr ':' constExpr ']' + { $$ = new AstSelExtract{$4, new AstDot{$2, false, $1, $3}, $5, $7}; } + | ~l~expr '.' function_subroutine_callNoMethod '[' expr yP_PLUSCOLON constExpr ']' + { $$ = new AstSelPlus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; } + | ~l~expr '.' function_subroutine_callNoMethod '[' expr yP_MINUSCOLON constExpr ']' + { $$ = new AstSelMinus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; } // // method_call:array_method requires a '.' - | ~l~expr '.' array_methodWith { $$ = new AstDot{$2, false, $1, $3}; } + | ~l~expr '.' array_methodWith + { $$ = new AstDot{$2, false, $1, $3}; } + | ~l~expr '.' array_methodWith '[' expr ']' + { $$ = new AstSelBit{$4, new AstDot{$2, false, $1, $3}, $5}; } + | ~l~expr '.' array_methodWith '[' constExpr ':' constExpr ']' + { $$ = new AstSelExtract{$4, new AstDot{$2, false, $1, $3}, $5, $7}; } + | ~l~expr '.' array_methodWith '[' expr yP_PLUSCOLON constExpr ']' + { $$ = new AstSelPlus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; } + | ~l~expr '.' array_methodWith '[' expr yP_MINUSCOLON constExpr ']' + { $$ = new AstSelMinus{$4, new AstDot{$2, false, $1, $3}, $5, $7}; } // // // IEEE: let_expression // // see funcRef @@ -5748,6 +5856,9 @@ clocking_eventE: // IEEE: optional clocking_event ; clocking_event: // IEEE: clocking_event + // // IEEE: '@' ps_identifier + // // IEEE: '@' hierarchical_identifier + //UNSUP: '@' idClassSel/*ps_identifier*/ '@' id { $$ = new AstSenItem{$2, VEdgeType::ET_CHANGED, new AstParseRef{$2, VParseRefExp::PX_TEXT, *$2, nullptr, nullptr}}; } @@ -6389,6 +6500,13 @@ covergroup_declaration: // ==IEEE: covergroup_declaration { $$ = $1; SYMP->popScope($$); GRAMMARP->endLabel($9, $1, $9); } + // // IEEE 1800-2023 added: + | covergroup_declarationFront yEXTENDS idAny/*covergroup_identifier*/ + /*cont*/ ';' coverage_spec_or_optionListE + /*cont*/ yENDGROUP endLabelE + { $$ = $1; + SYMP->popScope($$); + GRAMMARP->endLabel($7, $1, $7); } ; covergroup_declarationFront: // IEEE: part of covergroup_declaration @@ -6878,17 +6996,17 @@ class_declaration: // ==IEEE: part of class_declaration ; classFront: // IEEE: part of class_declaration - classVirtualE yCLASS lifetimeE idAny/*class_identifier*/ - { $$ = new AstClass{$2, *$4}; + // // IEEE 1800-2023: lifetimeE replaced with final_specifierE + classVirtualE yCLASS final_specifierE lifetimeE idAny/*class_identifier*/ + { $$ = new AstClass{$2, *$5}; $$->isVirtual($1); - $$->lifetime($3); SYMP->pushNew($$); v3Global.setHasClasses(); } // // IEEE: part of interface_class_declaration - | yINTERFACE yCLASS lifetimeE idAny/*class_identifier*/ - { $$ = new AstClass{$2, *$4}; + // // IEEE 1800-2023: lifetimeE removed + | yINTERFACE yCLASS idAny/*class_identifier*/ + { $$ = new AstClass{$2, *$3}; $$->isInterfaceClass(true); - $$->lifetime($3); SYMP->pushNew($$); v3Global.setHasClasses(); } ; @@ -7093,6 +7211,22 @@ class_method: // ==IEEE: class_method { $$ = $3; $2.applyToNodes($3); $3->isExternProto(true); } ; +dynamic_override_specifiersE: // IEEE: dynamic_override_specifiers or empty + /* empty */ { /* UNSUP-2023-ignored */ } + // // IEEE: Expanded [ initial_or_extends_specifier ] [ final_specifier ] + // // Note lifetime used by members is instead under memberQual + | ':' yINITIAL { /* UNSUP-2023-ignored */ } + | ':' yEXTENDS { /* UNSUP-2023-ignored */ } + | ':' yINITIAL ':' yFINAL { /* UNSUP-2023-ignored */ } + | ':' yEXTENDS ':' yFINAL { /* UNSUP-2023-ignored */ } + | ':' yFINAL { /* UNSUP-2023-ignored */ } + ; + +final_specifierE: // ==IEEE: final_specifier (similar to dynamic_override_specifiers) + /* empty */ { } + | ':' yFINAL { /* UNSUP-2023-ignored */ } + ; + // IEEE: class_constructor_prototype // See function_declaration @@ -7129,13 +7263,13 @@ class_constraint: // ==IEEE: class_constraint // // IEEE: constraint_declaration // // UNSUP: We have the unsupported warning on the randomize() call, so don't bother on // // constraint blocks. When we support randomize we need to make AST nodes for below rules - constraintStaticE yCONSTRAINT constraintIdNew constraint_block - { $$ = $3; $$->isStatic($1); $$->addItemsp($4); SYMP->popScope($$); } - | constraintStaticE yCONSTRAINT constraintIdNew '{' '}' - { $$ = $3; $$->isStatic($1); SYMP->popScope($$); } + constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew constraint_block + { $$ = $4; $$->isStatic($1); $$->addItemsp($5); SYMP->popScope($$); } + | constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew '{' '}' + { $$ = $4; $$->isStatic($1); SYMP->popScope($$); } // // IEEE: constraint_prototype + constraint_prototype_qualifier - | constraintStaticE yCONSTRAINT constraintIdNew ';' - { $$ = $3; $$->isStatic($1); SYMP->popScope($$); } + | constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';' + { $$ = $4; $$->isStatic($1); SYMP->popScope($$); } | yEXTERN constraintStaticE yCONSTRAINT constraintIdNew ';' { $$ = $4; $$->isStatic($1); SYMP->popScope($4); BBUNSUP($1, "Unsupported: extern constraint"); } @@ -7172,7 +7306,7 @@ solve_before_list: // ==IEEE: solve_before_list constraint_primary: // ==IEEE: constraint_primary // // exprScope more general than: - // // [ implicit_class_handle '.' | class_scope ] hierarchical_identifier select + // // [ implicit_class_handle '.' | class_scope ] hierarchical_identifier select [ '(' ')' ] exprScope { $$ = $1; } ; @@ -7227,10 +7361,14 @@ dist_item: // ==IEEE: dist_item + dist_weight { $$ = new AstDistItem{$2, $1, $3}; } | value_range yP_COLONDIV expr { $$ = new AstDistItem{$2, $1, $3}; $$->isWhole(true); } + // // IEEE 1800-2023 added: + | yDEFAULT yP_COLONDIV expr + { BBUNSUP($2, "Unsupported: 'default :/' constraint"); + $$ = nullptr; } ; extern_constraint_declaration: // ==IEEE: extern_constraint_declaration - constraintStaticE yCONSTRAINT packageClassScopeE idAny constraint_block + constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE idAny constraint_block { $$ = nullptr; BBUNSUP($2, "Unsupported: extern constraint"); } ; diff --git a/test_regress/t/t_assoc_method.v b/test_regress/t/t_assoc_method.v index 5d923470f..21414053b 100644 --- a/test_regress/t/t_assoc_method.v +++ b/test_regress/t/t_assoc_method.v @@ -106,7 +106,7 @@ module t (/*AUTOARG*/); // Reduction methods - i = q.sum; + i = q.sum; `checkh(i, 32'hc); i = q.sum with (item + 1); `checkh(i, 32'h11); diff --git a/test_regress/t/t_bitsel_concat.pl b/test_regress/t/t_bitsel_concat.pl new file mode 100755 index 000000000..b46d46042 --- /dev/null +++ b/test_regress/t/t_bitsel_concat.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_bitsel_concat.v b/test_regress/t/t_bitsel_concat.v new file mode 100644 index 000000000..c18aa2c2e --- /dev/null +++ b/test_regress/t/t_bitsel_concat.v @@ -0,0 +1,91 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// A test case for struct signal bit selection. +// +// This test is to check that bit selection of multi-dimensional signal inside +// of a packed struct works. Currently +: and -: blow up with packed structs. +// +// This file ONLY is placed into the Public Domain, for any use, without +// warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); + +// Test IEEE 1800-2023 concat bit selects, function bit selects, method bit selects + +class Cls; + static function logic [15:0] valf1ed(); + return 16'hf1ed; + endfunction +endclass + +module t(/*AUTOARG*/); + + Cls c; + + int q[$]; + + logic [7:0] aa; + logic [7:0] bb; + logic [7:0] s8; + logic s1; + + function logic [15:0] valf0ed(); + return 16'hf0ed; + endfunction + + initial begin + aa = 8'haa; + bb = 8'hbb; + + s1 = {aa,bb}[8]; + `checkh(s1, 1'b0); + s1 = {aa,bb}[9]; + `checkh(s1, 1'b1); + s8 = {aa,bb}[11:4]; + `checkh(s8, 8'hab); + s8 = {aa,bb}[4+:8]; + `checkh(s8, 8'hab); + s8 = {aa,bb}[11-:8]; + `checkh(s8, 8'hab); + + s1 = valf0ed()[4]; + `checkh(s1, 1'b0); + s1 = valf0ed()[5]; + `checkh(s1, 1'b1); + s8 = valf0ed()[11:4]; + `checkh(s8, 8'h0e); + s8 = valf0ed()[4+:8]; + `checkh(s8, 8'h0e); + s8 = valf0ed()[11-:8]; + `checkh(s8, 8'h0e); + + c = new; + s1 = c.valf1ed()[4]; + `checkh(s1, 1'b0); + s1 = c.valf1ed()[5]; + `checkh(s1, 1'b1); + s8 = c.valf1ed()[11:4]; + `checkh(s8, 8'h1e); + s8 = c.valf1ed()[4+:8]; + `checkh(s8, 8'h1e); + s8 = c.valf1ed()[11-:8]; + `checkh(s8, 8'h1e); + + q.push_front(32'h10ef); + s1 = q.sum()[4]; + `checkh(s1, 1'b0); + s1 = q.sum()[5]; + `checkh(s1, 1'b1); + s8 = q.sum()[11:4]; + `checkh(s8, 8'h0e); + s8 = q.sum()[4+:8]; + `checkh(s8, 8'h0e); + s8 = q.sum()[11-:8]; + `checkh(s8, 8'h0e); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_class_new_default.out b/test_regress/t/t_class_new_default.out new file mode 100644 index 000000000..1ddd26248 --- /dev/null +++ b/test_regress/t/t_class_new_default.out @@ -0,0 +1,11 @@ +%Error-UNSUPPORTED: t/t_class_new_default.v:10:17: Unsupported: new constructor 'default' argument + 10 | function new(default); + | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_class_new_default.v:17:24: Unsupported: new constructor 'default' argument + 17 | extern function new(default); + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_class_new_default.v:20:25: Unsupported: new constructor 'default' argument + 20 | function ClsDefFwd::new(default); + | ^~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_class_new_default.pl b/test_regress/t/t_class_new_default.pl new file mode 100755 index 000000000..009248fc5 --- /dev/null +++ b/test_regress/t/t_class_new_default.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_new_default.v b/test_regress/t/t_class_new_default.v new file mode 100644 index 000000000..49665ac4d --- /dev/null +++ b/test_regress/t/t_class_new_default.v @@ -0,0 +1,28 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + + +class ClsDef; + int imembera; + function new(default); + imembera = i + 1; + endfunction +endclass + +class ClsDefFwd; + int imembera; + extern function new(default); +endclass + +function ClsDefFwd::new(default); +endfunction + +module t (/*AUTOARG*/); + initial begin + // TODO real test + $stop; + end +endmodule diff --git a/test_regress/t/t_covergroup_unsup.out b/test_regress/t/t_covergroup_unsup.out index 6a6747e11..808facb6d 100644 --- a/test_regress/t/t_covergroup_unsup.out +++ b/test_regress/t/t_covergroup_unsup.out @@ -377,4 +377,7 @@ %Error-UNSUPPORTED: t/t_covergroup_unsup.v:133:7: Unsupported: cross 133 | cross a, b { | ^~~~~ +%Error-UNSUPPORTED: t/t_covergroup_unsup.v:151:4: Unsupported: covergroup + 151 | covergroup cg_more extends cg_empty; + | ^~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_covergroup_unsup.v b/test_regress/t/t_covergroup_unsup.v index 6fed272bc..1d8dcade6 100644 --- a/test_regress/t/t_covergroup_unsup.v +++ b/test_regress/t/t_covergroup_unsup.v @@ -148,6 +148,9 @@ module t (/*AUTOARG*/ } endgroup + covergroup cg_more extends cg_empty; + endgroup + always @(posedge clk) begin if (cyc == 10) begin $write("*-* All Finished *-*\n"); diff --git a/test_regress/t/t_param_type_fwd.out b/test_regress/t/t_param_type_fwd.out new file mode 100644 index 000000000..e2b38098f --- /dev/null +++ b/test_regress/t/t_param_type_fwd.out @@ -0,0 +1,32 @@ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:10:4: Unsupported: 'parameter type' forward type + 10 | parameter type enum E_t; + | ^~~~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_param_type_fwd.v:11:4: Unsupported: 'parameter type' forward type + 11 | parameter type struct S_t; + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:12:4: Unsupported: 'parameter type' forward type + 12 | parameter type union U_t; + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:13:4: Unsupported: 'parameter type' forward type + 13 | parameter type class C_t; + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:14:4: Unsupported: 'parameter type' forward type + 14 | parameter type interface class IC_t; + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:17:13: Unsupported: 'parameter type' forward type + 17 | class Cls #(parameter type enum E_t, + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:18:13: Unsupported: 'parameter type' forward type + 18 | parameter type struct S_t, + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:19:13: Unsupported: 'parameter type' forward type + 19 | parameter type union U_t, + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:20:13: Unsupported: 'parameter type' forward type + 20 | parameter type class C_t, + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_param_type_fwd.v:21:13: Unsupported: 'parameter type' forward type + 21 | parameter type interface class IC_t); + | ^~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_param_type_fwd.pl b/test_regress/t/t_param_type_fwd.pl new file mode 100755 index 000000000..a5846c699 --- /dev/null +++ b/test_regress/t/t_param_type_fwd.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_param_type_fwd.v b/test_regress/t/t_param_type_fwd.v new file mode 100644 index 000000000..375495398 --- /dev/null +++ b/test_regress/t/t_param_type_fwd.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// Test for trace file interface aliasing + +module m; + parameter type enum E_t; + parameter type struct S_t; + parameter type union U_t; + parameter type class C_t; + parameter type interface class IC_t; +endmodule + +class Cls #(parameter type enum E_t, + parameter type struct S_t, + parameter type union U_t, + parameter type class C_t, + parameter type interface class IC_t); +endclass + +module t (/*AUTOARG*/); + // TODO proper test +endmodule diff --git a/test_regress/t/t_union_soft.out b/test_regress/t/t_union_soft.out new file mode 100644 index 000000000..35fd986e9 --- /dev/null +++ b/test_regress/t/t_union_soft.out @@ -0,0 +1,5 @@ +%Error-UNSUPPORTED: t/t_union_soft.v:9:10: Unsupported: 'union soft' + 9 | union soft { + | ^~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_union_soft.pl b/test_regress/t/t_union_soft.pl new file mode 100755 index 000000000..a5846c699 --- /dev/null +++ b/test_regress/t/t_union_soft.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_union_soft.v b/test_regress/t/t_union_soft.v new file mode 100644 index 000000000..7bbec350f --- /dev/null +++ b/test_regress/t/t_union_soft.v @@ -0,0 +1,25 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + + union soft { + bit [7:0] val1; + bit [3:0] val2; + } u; + + initial begin + u.val1 = 8'h7c; + if (u.val1 != 8'h7c) $stop; + u.val2 = 4'h6; + if (u.val2 != 4'h6) $stop; + $display("%p", u); + if (u.ual1 != 8'h76) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_var_ref_static.out b/test_regress/t/t_var_ref_static.out new file mode 100644 index 000000000..830fd1304 --- /dev/null +++ b/test_regress/t/t_var_ref_static.out @@ -0,0 +1,8 @@ +%Error-UNSUPPORTED: t/t_var_ref_static.v:12:22: Unsupported: 'ref static' ports + 12 | function void crs(const ref static i); + | ^~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_var_ref_static.v:14:21: Unsupported: 'ref static' ports + 14 | function void rs(ref static i); + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_var_ref_static.pl b/test_regress/t/t_var_ref_static.pl new file mode 100755 index 000000000..a5846c699 --- /dev/null +++ b/test_regress/t/t_var_ref_static.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vlt => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_var_ref_static.v b/test_regress/t/t_var_ref_static.v new file mode 100644 index 000000000..1d3a248c9 --- /dev/null +++ b/test_regress/t/t_var_ref_static.v @@ -0,0 +1,16 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// Make sure type errors aren't suppressable +// verilator lint_off WIDTH + +module t; + // TODO make this a proper test + function void crs(const ref static i); + endfunction + function void rs(ref static i); + endfunction +endmodule