From b5fdf06475e690ca6db5e0e2bb7749c1c0f9256b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 3 Aug 2026 19:57:03 -0700 Subject: [PATCH] Add regression tests for elaborated cast targets Check a type cast with an inline packed dimension and reject dimensions following a type identifier in a cast target. Use a dimensioned typedef in the reject test to distinguish dimensions in the type from dimensions after the identifier. Check that an error reported while elaborating a cast-target type is emitted only once when width checking and expression elaboration reuse the cached target information. Also check that each module instance resolves a type-parameter cast target using its own parameter value. Check that typed dynamic-array elaboration constructs the explicit cast target rather than the enclosing expression type. Run the tests through the native and vlog95 backends. Signed-off-by: Lars-Peter Clausen --- ...t_indexed_target_fail-iverilog-stderr.gold | 3 ++ ..._type_error_once_fail-iverilog-stderr.gold | 4 ++ ivtest/ivltests/sv_cast_darray_target.v | 26 +++++++++++++ ivtest/ivltests/sv_cast_indexed_target_fail.v | 12 ++++++ ivtest/ivltests/sv_cast_type_dimension.v | 17 +++++++++ .../ivltests/sv_cast_type_error_once_fail.v | 11 ++++++ .../ivltests/sv_cast_type_parameter_scope.v | 38 +++++++++++++++++++ ivtest/regress-vvp.list | 5 +++ ivtest/vvp_tests/sv_cast_darray_target.json | 9 +++++ .../sv_cast_indexed_target_fail.json | 6 +++ ivtest/vvp_tests/sv_cast_type_dimension.json | 5 +++ .../sv_cast_type_error_once_fail.json | 6 +++ .../sv_cast_type_parameter_scope.json | 5 +++ 13 files changed, 147 insertions(+) create mode 100644 ivtest/gold/sv_cast_indexed_target_fail-iverilog-stderr.gold create mode 100644 ivtest/gold/sv_cast_type_error_once_fail-iverilog-stderr.gold create mode 100644 ivtest/ivltests/sv_cast_darray_target.v create mode 100644 ivtest/ivltests/sv_cast_indexed_target_fail.v create mode 100644 ivtest/ivltests/sv_cast_type_dimension.v create mode 100644 ivtest/ivltests/sv_cast_type_error_once_fail.v create mode 100644 ivtest/ivltests/sv_cast_type_parameter_scope.v create mode 100644 ivtest/vvp_tests/sv_cast_darray_target.json create mode 100644 ivtest/vvp_tests/sv_cast_indexed_target_fail.json create mode 100644 ivtest/vvp_tests/sv_cast_type_dimension.json create mode 100644 ivtest/vvp_tests/sv_cast_type_error_once_fail.json create mode 100644 ivtest/vvp_tests/sv_cast_type_parameter_scope.json diff --git a/ivtest/gold/sv_cast_indexed_target_fail-iverilog-stderr.gold b/ivtest/gold/sv_cast_indexed_target_fail-iverilog-stderr.gold new file mode 100644 index 000000000..cc0df6075 --- /dev/null +++ b/ivtest/gold/sv_cast_indexed_target_fail-iverilog-stderr.gold @@ -0,0 +1,3 @@ +ivltests/sv_cast_indexed_target_fail.v:9: error: Dimensions after a type identifier are not allowed in a cast target. +ivltests/sv_cast_indexed_target_fail.v:5: : The type was declared here. +Elaboration failed diff --git a/ivtest/gold/sv_cast_type_error_once_fail-iverilog-stderr.gold b/ivtest/gold/sv_cast_type_error_once_fail-iverilog-stderr.gold new file mode 100644 index 000000000..26ecb7148 --- /dev/null +++ b/ivtest/gold/sv_cast_type_error_once_fail-iverilog-stderr.gold @@ -0,0 +1,4 @@ +ivltests/sv_cast_type_error_once_fail.v:8: error: Unable to bind parameter `missing' in `test' +ivltests/sv_cast_type_error_once_fail.v:8: error: Dimensions must be a constant with no unknown or high-Z bits. +ivltests/sv_cast_type_error_once_fail.v:8 : This MSB expression violates the rule: missing +2 error(s) during elaboration. diff --git a/ivtest/ivltests/sv_cast_darray_target.v b/ivtest/ivltests/sv_cast_darray_target.v new file mode 100644 index 000000000..7e14ce591 --- /dev/null +++ b/ivtest/ivltests/sv_cast_darray_target.v @@ -0,0 +1,26 @@ +// Check that typed elaboration uses the explicit cast target type. + +module test; + + typedef logic scalar_t; + typedef scalar_t [7:0] packed_byte_t; + typedef logic [7:0] byte_array_t[]; + + packed_byte_t result[]; + bit failed = 1'b0; + + initial begin + result = byte_array_t'(16'h12ab); + + if (result.size() != 2 || result[0] !== 8'h12 || + result[1] !== 8'hab) begin + $display("FAILED(%0d). Incorrect result", `__LINE__); + failed = 1'b1; + end + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_cast_indexed_target_fail.v b/ivtest/ivltests/sv_cast_indexed_target_fail.v new file mode 100644 index 000000000..dacccee60 --- /dev/null +++ b/ivtest/ivltests/sv_cast_indexed_target_fail.v @@ -0,0 +1,12 @@ +// Check that dimensions cannot follow a type identifier in a cast target. + +module test; + + typedef logic [7:0] T; + logic [7:0] value; + + initial begin + value = T[3:0]'(1); + end + +endmodule diff --git a/ivtest/ivltests/sv_cast_type_dimension.v b/ivtest/ivltests/sv_cast_type_dimension.v new file mode 100644 index 000000000..d9ffbb9d4 --- /dev/null +++ b/ivtest/ivltests/sv_cast_type_dimension.v @@ -0,0 +1,17 @@ +// Check an inline packed dimension in a type cast. + +module test; + + logic [7:0] result; + + initial begin + result = logic [3:0]'(8'haf); + + if (result !== 8'h0f) begin + $display("FAILED(%0d). Expected 0f, got %h", `__LINE__, result); + end else begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_cast_type_error_once_fail.v b/ivtest/ivltests/sv_cast_type_error_once_fail.v new file mode 100644 index 000000000..3a0438613 --- /dev/null +++ b/ivtest/ivltests/sv_cast_type_error_once_fail.v @@ -0,0 +1,11 @@ +// Check that a cast target type is elaborated only once. + +module test; + + logic [7:0] value; + + initial begin + value = logic [missing:0]'(1); + end + +endmodule diff --git a/ivtest/ivltests/sv_cast_type_parameter_scope.v b/ivtest/ivltests/sv_cast_type_parameter_scope.v new file mode 100644 index 000000000..efb817f65 --- /dev/null +++ b/ivtest/ivltests/sv_cast_type_parameter_scope.v @@ -0,0 +1,38 @@ +// Check that a cast target type is resolved separately for each instance. + +module M #( + parameter type T = logic [3:0], + parameter integer EXPECTED_WIDTH = 4 +) ( + output reg failed +); + + initial begin + failed = 1'b0; + + if ($bits(T'(0)) !== EXPECTED_WIDTH) begin + $display("FAILED(%0d). Expected %0d, got %0d", `__LINE__, + EXPECTED_WIDTH, $bits(T'(0))); + failed = 1'b1; + end + end + +endmodule + +module test; + + wire failed4; + wire failed8; + + M #(.T(logic [3:0]), .EXPECTED_WIDTH(4)) i4(.failed(failed4)); + M #(.T(logic [7:0]), .EXPECTED_WIDTH(8)) i8(.failed(failed8)); + + initial begin + #1; + + if (!failed4 && !failed8) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index a6c168359..0f326458b 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -284,6 +284,11 @@ sv_byte_array_string_fail3 vvp_tests/sv_byte_array_string_fail3.json sv_byte_array_string_fail4 vvp_tests/sv_byte_array_string_fail4.json sv_byte_array_string_fail5 vvp_tests/sv_byte_array_string_fail5.json sv_call_chain_method1 vvp_tests/sv_call_chain_method1.json +sv_cast_darray_target vvp_tests/sv_cast_darray_target.json +sv_cast_indexed_target_fail vvp_tests/sv_cast_indexed_target_fail.json +sv_cast_type_dimension vvp_tests/sv_cast_type_dimension.json +sv_cast_type_error_once_fail vvp_tests/sv_cast_type_error_once_fail.json +sv_cast_type_parameter_scope vvp_tests/sv_cast_type_parameter_scope.json sv_chained_constructor1 vvp_tests/sv_chained_constructor1.json sv_chained_constructor2 vvp_tests/sv_chained_constructor2.json sv_chained_constructor3 vvp_tests/sv_chained_constructor3.json diff --git a/ivtest/vvp_tests/sv_cast_darray_target.json b/ivtest/vvp_tests/sv_cast_darray_target.json new file mode 100644 index 000000000..4a9adc8b8 --- /dev/null +++ b/ivtest/vvp_tests/sv_cast_darray_target.json @@ -0,0 +1,9 @@ +{ + "type" : "normal", + "source" : "sv_cast_darray_target.v", + "iverilog-args" : [ "-g2005-sv" ], + "vlog95" : { + "__comment" : "SystemVerilog dynamic arrays are not supported", + "type" : "CE" + } +} diff --git a/ivtest/vvp_tests/sv_cast_indexed_target_fail.json b/ivtest/vvp_tests/sv_cast_indexed_target_fail.json new file mode 100644 index 000000000..fcad19df8 --- /dev/null +++ b/ivtest/vvp_tests/sv_cast_indexed_target_fail.json @@ -0,0 +1,6 @@ +{ + "type" : "CE", + "source" : "sv_cast_indexed_target_fail.v", + "gold" : "sv_cast_indexed_target_fail", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_cast_type_dimension.json b/ivtest/vvp_tests/sv_cast_type_dimension.json new file mode 100644 index 000000000..2c0480a1a --- /dev/null +++ b/ivtest/vvp_tests/sv_cast_type_dimension.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_cast_type_dimension.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_cast_type_error_once_fail.json b/ivtest/vvp_tests/sv_cast_type_error_once_fail.json new file mode 100644 index 000000000..6c94c5518 --- /dev/null +++ b/ivtest/vvp_tests/sv_cast_type_error_once_fail.json @@ -0,0 +1,6 @@ +{ + "type" : "CE", + "source" : "sv_cast_type_error_once_fail.v", + "gold" : "sv_cast_type_error_once_fail", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_cast_type_parameter_scope.json b/ivtest/vvp_tests/sv_cast_type_parameter_scope.json new file mode 100644 index 000000000..b945e3799 --- /dev/null +++ b/ivtest/vvp_tests/sv_cast_type_parameter_scope.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_cast_type_parameter_scope.v", + "iverilog-args" : [ "-g2005-sv" ] +}