From 20a34d33c690b51b2788feb083030aece483bd2c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 9 Jul 2026 20:05:46 -0700 Subject: [PATCH 1/2] parser: Reject implicit parameter types without `parameter` The LRM allows omitting the `parameter` keyword in a module parameter port list, but the optional type in that form is a data_type, not an implicit data type. A parameter port list like this is therefore invalid: module M #([3:0] P = 1); The parameter declaration grammar was reusing the general value_parameter_assign_with_type rule for the omitted-keyword form. That rule also accepts implicit types so that ordinary `parameter signed P = 1` declarations work, which made the omitted-keyword form accept implicit types as well. Add a separate rule for value parameter assignments without the `parameter` keyword. The rule still accepts bare identifiers and explicit data types so a parameter name can shadow a visible typedef name, but it rejects implicit types. Fixes: e56c93a2be56 ("Support shadowing type identifiers in parameter declarations") Signed-off-by: Lars-Peter Clausen --- parse.y | 59 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/parse.y b/parse.y index 6f9edcf15..f8cc4225a 100644 --- a/parse.y +++ b/parse.y @@ -1020,6 +1020,8 @@ Module::port_t *module_declare_interface_port(const YYLTYPE&loc, char *type, %type data_type_or_implicit_plus_id %type data_type_or_implicit_plus_id_dim %type data_type_or_implicit_or_void_plus_id +%type data_type_or_parameter_id_base +%type data_type_or_parameter_id_dim %type partial_port_name_dim %type partial_port_type_plus_id_dim %type partial_port_typedef_plus_id_dim @@ -2787,6 +2789,33 @@ data_type_or_implicit_plus_id_dim } ; + // Parameter port lists can omit the `parameter` keyword, but the optional + // type in that form is a data_type, not data_type_or_implicit. Keep this + // separate from data_type_or_implicit_plus_id_dim so a bare typedef name can + // still be parsed as a parameter name while implicit types like `signed P` + // and `[3:0] P` are rejected. +data_type_or_parameter_id_base + : IDENTIFIER + { set_type_id_range($$, nullptr, $1, @1, nullptr); + } + | atomic_type identifier_name + { set_type_id_range($$, $1, $2, @2, nullptr); + } + | ps_type_identifier_dim identifier_name + { set_type_id_range($$, $1, $2, @2, nullptr); + } + ; + +data_type_or_parameter_id_dim + : TYPE_IDENTIFIER dimensions_opt + { set_type_id_range($$, nullptr, $1.text, @1, $2); + } + | data_type_or_parameter_id_base dimensions_opt + { $$ = $1; + $$.ranges = $2; + } + ; + // `void` is only an explicit return type. The following identifier is still a // function name and may be tokenized as TYPE_IDENTIFIER when it shadows a // visible type name. @@ -5271,7 +5300,7 @@ module_parameter module_parameter_port_list : module_parameter - | value_parameter_assign_with_type + | value_parameter_assign_without_parameter { pform_requires_sv(@1, "Omitting initial `parameter` in parameter port " "list"); } @@ -5951,10 +5980,28 @@ value_parameter_assign_with_type } ; +value_parameter_assign_without_parameter + : data_type_or_parameter_id_dim initializer_opt parameter_value_ranges_opt + { param_is_type = false; + param_type_restrict = {}; + param_data_type = $1.type; + YYLTYPE id_loc = @1; + id_loc.first_line = $1.first_line; + id_loc.first_column = $1.first_column; + id_loc.last_line = $1.last_line; + id_loc.last_column = $1.last_column; + id_loc.lexical_pos = $1.lexical_pos; + pform_set_parameter(id_loc, $1.id, param_is_local, + param_is_type, param_type_restrict, + param_data_type, $1.ranges, $2, $3); + } + ; + // Parameter port lists allow an explicit type after a comma without // repeating `parameter`, e.g. `#(parameter p = 1, int q = 2)`. Keep this // narrower than value_parameter_assign_with_type so a bare typedef name - // after a comma remains a parameter name that inherits the previous type. + // after a comma remains a parameter name that inherits the previous type. The + // LRM allows data_type here, but not implicit_type. value_parameter_assign_with_explicit_type : atomic_type identifier_name dimensions_opt initializer_opt parameter_value_ranges_opt { param_is_type = false; @@ -5964,14 +6011,6 @@ value_parameter_assign_with_explicit_type param_is_type, param_type_restrict, param_data_type, $3, $4, $5); } - | implicit_type identifier_name dimensions_opt initializer_opt parameter_value_ranges_opt - { param_is_type = false; - param_type_restrict = {}; - param_data_type = $1; - pform_set_parameter(@2, $2, param_is_local, - param_is_type, param_type_restrict, - param_data_type, $3, $4, $5); - } | ps_type_identifier_dim identifier_name dimensions_opt initializer_opt parameter_value_ranges_opt { param_is_type = false; param_type_restrict = {}; From c0cf842eb21a8eb000c6d89b78d63b237e32066d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 9 Jul 2026 20:13:44 -0700 Subject: [PATCH 2/2] ivtest: Move parameter omit tests to JSON The parameter_omit tests have different expectations depending on whether the regression is run in the default Verilog mode or with force SystemVerilog. The old list files modelled this by registering the same tests in both regress-vlg.list and regress-fsv.list. Move the tests to JSON descriptors. Use the existing force-sv override for the forms that are valid SystemVerilog, and keep the implicit type cases as CE in both modes. This also runs the tests through the additional configurations supported by vvp_reg.py, providing better coverage in CI. Signed-off-by: Lars-Peter Clausen --- ivtest/regress-fsv.list | 3 --- ivtest/regress-vlg.list | 6 ------ ivtest/regress-vvp.list | 6 ++++++ ivtest/vvp_tests/parameter_omit1.json | 7 +++++++ ivtest/vvp_tests/parameter_omit2.json | 7 +++++++ ivtest/vvp_tests/parameter_omit3.json | 7 +++++++ ivtest/vvp_tests/parameter_omit_invalid1.json | 4 ++++ ivtest/vvp_tests/parameter_omit_invalid2.json | 4 ++++ ivtest/vvp_tests/parameter_omit_invalid3.json | 4 ++++ 9 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 ivtest/vvp_tests/parameter_omit1.json create mode 100644 ivtest/vvp_tests/parameter_omit2.json create mode 100644 ivtest/vvp_tests/parameter_omit3.json create mode 100644 ivtest/vvp_tests/parameter_omit_invalid1.json create mode 100644 ivtest/vvp_tests/parameter_omit_invalid2.json create mode 100644 ivtest/vvp_tests/parameter_omit_invalid3.json diff --git a/ivtest/regress-fsv.list b/ivtest/regress-fsv.list index afe656c74..462c5ded3 100644 --- a/ivtest/regress-fsv.list +++ b/ivtest/regress-fsv.list @@ -84,9 +84,6 @@ module_input_port_list_def normal ivltests module_input_port_type normal ivltests parameter_in_generate1 normal ivltests parameter_no_default normal ivltests -parameter_omit1 normal ivltests -parameter_omit2 normal ivltests -parameter_omit3 normal ivltests pr3015421 CE ivltests gold=pr3015421-fsv.gold resetall normal,-Wtimescale ivltests gold=resetall-fsv.gold scope2b normal ivltests diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index 55fbc8cc5..a2a1f86ed 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -761,12 +761,6 @@ param_times normal ivltests # param has multiplication. parameter_1bit normal ivltests parameter_in_generate1 CE ivltests parameter_no_default CE ivltests -parameter_omit1 CE ivltests -parameter_omit2 CE ivltests -parameter_omit3 CE ivltests -parameter_omit_invalid1 CE ivltests -parameter_omit_invalid2 CE ivltests -parameter_omit_invalid3 CE ivltests parameter_override_invalid1 CE ivltests parameter_override_invalid2 CE ivltests parameter_override_invalid3 CE ivltests diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index e8d021038..86489f83a 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -371,6 +371,12 @@ sv_net_array_decl_assign vvp_tests/sv_net_array_decl_assign.json sv_net_decl_assign vvp_tests/sv_net_decl_assign.json sv_package_lifetime vvp_tests/sv_package_lifetime.json sv_package_lifetime_fail vvp_tests/sv_package_lifetime_fail.json +parameter_omit1 vvp_tests/parameter_omit1.json +parameter_omit2 vvp_tests/parameter_omit2.json +parameter_omit3 vvp_tests/parameter_omit3.json +parameter_omit_invalid1 vvp_tests/parameter_omit_invalid1.json +parameter_omit_invalid2 vvp_tests/parameter_omit_invalid2.json +parameter_omit_invalid3 vvp_tests/parameter_omit_invalid3.json sv_parameter_type vvp_tests/sv_parameter_type.json sv_partsel_var_negative_packed vvp_tests/sv_partsel_var_negative_packed.json sv_queue_ap_method vvp_tests/sv_queue_ap_method.json diff --git a/ivtest/vvp_tests/parameter_omit1.json b/ivtest/vvp_tests/parameter_omit1.json new file mode 100644 index 000000000..3dd77e1cd --- /dev/null +++ b/ivtest/vvp_tests/parameter_omit1.json @@ -0,0 +1,7 @@ +{ + "type" : "CE", + "source" : "parameter_omit1.v", + "force-sv" : { + "type" : "normal" + } +} diff --git a/ivtest/vvp_tests/parameter_omit2.json b/ivtest/vvp_tests/parameter_omit2.json new file mode 100644 index 000000000..cb09ba0c4 --- /dev/null +++ b/ivtest/vvp_tests/parameter_omit2.json @@ -0,0 +1,7 @@ +{ + "type" : "CE", + "source" : "parameter_omit2.v", + "force-sv" : { + "type" : "normal" + } +} diff --git a/ivtest/vvp_tests/parameter_omit3.json b/ivtest/vvp_tests/parameter_omit3.json new file mode 100644 index 000000000..9970cd8d1 --- /dev/null +++ b/ivtest/vvp_tests/parameter_omit3.json @@ -0,0 +1,7 @@ +{ + "type" : "CE", + "source" : "parameter_omit3.v", + "force-sv" : { + "type" : "normal" + } +} diff --git a/ivtest/vvp_tests/parameter_omit_invalid1.json b/ivtest/vvp_tests/parameter_omit_invalid1.json new file mode 100644 index 000000000..d906a0c44 --- /dev/null +++ b/ivtest/vvp_tests/parameter_omit_invalid1.json @@ -0,0 +1,4 @@ +{ + "type" : "CE", + "source" : "parameter_omit_invalid1.v" +} diff --git a/ivtest/vvp_tests/parameter_omit_invalid2.json b/ivtest/vvp_tests/parameter_omit_invalid2.json new file mode 100644 index 000000000..a3205e5ad --- /dev/null +++ b/ivtest/vvp_tests/parameter_omit_invalid2.json @@ -0,0 +1,4 @@ +{ + "type" : "CE", + "source" : "parameter_omit_invalid2.v" +} diff --git a/ivtest/vvp_tests/parameter_omit_invalid3.json b/ivtest/vvp_tests/parameter_omit_invalid3.json new file mode 100644 index 000000000..106baed2c --- /dev/null +++ b/ivtest/vvp_tests/parameter_omit_invalid3.json @@ -0,0 +1,4 @@ +{ + "type" : "CE", + "source" : "parameter_omit_invalid3.v" +}