From 37eba70ca4a4c368e074ece0f65755f99fb43396 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Thu, 16 Nov 2023 09:21:54 +0100 Subject: [PATCH 1/5] eval_tree: Indent fixes Signed-off-by: Sylvain Munaut --- eval_tree.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eval_tree.cc b/eval_tree.cc index 04e9975e3..b9e0ccdda 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -2172,10 +2172,10 @@ static bool get_array_info(const NetExpr*arg, long dim, long &left, long &right, bool&defer) { if (const NetEConstParam*param = dynamic_cast(arg)) { - ivl_assert(*arg, dim == 1); - left = param->expr_width() - 1; - right = 0; - return false; + ivl_assert(*arg, dim == 1); + left = param->expr_width() - 1; + right = 0; + return false; } /* The argument must be a signal that has enough dimensions. */ const NetESignal*esig = dynamic_cast(arg); From 8ca387d6dee264b78cede6da366407cb276842bf Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Wed, 15 Nov 2023 21:14:24 +0100 Subject: [PATCH 2/5] eval_tree: Properly support struct fields in get_array_info Fixes #1032 Signed-off-by: Sylvain Munaut --- eval_tree.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/eval_tree.cc b/eval_tree.cc index b9e0ccdda..df8680d73 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -2176,6 +2176,13 @@ static bool get_array_info(const NetExpr*arg, long dim, left = param->expr_width() - 1; right = 0; return false; + } + if (const NetESelect*select = dynamic_cast(arg)) { + const netranges_t&dim_vals = select->net_type()->slice_dimensions(); + const netrange_t&range = dim_vals[dim-1]; + left = range.get_msb(); + right = range.get_lsb(); + return false; } /* The argument must be a signal that has enough dimensions. */ const NetESignal*esig = dynamic_cast(arg); From d564cecfb982c630f123d57fcf4c2fd40d80ead7 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Thu, 16 Nov 2023 09:24:41 +0100 Subject: [PATCH 3/5] ivtest: Add test for $left / $right on structure field See issue #1032 Signed-off-by: Sylvain Munaut --- ivtest/ivltests/struct_field_left_right.v | 23 +++++++++++++++++++ ivtest/regress-vvp.list | 1 + ivtest/vvp_tests/struct_field_left_right.json | 5 ++++ 3 files changed, 29 insertions(+) create mode 100644 ivtest/ivltests/struct_field_left_right.v create mode 100644 ivtest/vvp_tests/struct_field_left_right.json diff --git a/ivtest/ivltests/struct_field_left_right.v b/ivtest/ivltests/struct_field_left_right.v new file mode 100644 index 000000000..a7f138376 --- /dev/null +++ b/ivtest/ivltests/struct_field_left_right.v @@ -0,0 +1,23 @@ +module main; + + typedef struct packed { + logic [15:8] f; + } structtype; + + structtype s; + + initial + begin + $display("$left(s.f) = %2d, $right(s.f) = %2d", $left(s.f), $right(s.f)); + if ($left(s.f) !== 15) begin + $display("FAILED -- $left(s.f) = %2d", $left(s.f)); + $finish; + end + if ($right(s.f) !== 8) begin + $display("FAILED -- $right(s.f) = %2d", $right(s.f)); + $finish; + end + $display("PASSED"); + end + +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 1cb5a3912..1c5f24bb5 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -46,6 +46,7 @@ pr903 vvp_tests/pr903.json pr903-vlog95 vvp_tests/pr903-vlog95.json pv_wr_fn_vec2 vvp_tests/pv_wr_fn_vec2.json pv_wr_fn_vec4 vvp_tests/pv_wr_fn_vec4.json +struct_field_left_right vvp_tests/struct_field_left_right.json struct_packed_write_read vvp_tests/struct_packed_write_read.json struct_packed_write_read2 vvp_tests/struct_packed_write_read2.json sv_2state_array_init_prop vvp_tests/sv_2state_array_init_prop.json diff --git a/ivtest/vvp_tests/struct_field_left_right.json b/ivtest/vvp_tests/struct_field_left_right.json new file mode 100644 index 000000000..a3cdb9f34 --- /dev/null +++ b/ivtest/vvp_tests/struct_field_left_right.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "struct_field_left_right.v", + "iverilog-args" : [ "-g2009" ] +} From e0b255f34f2a701a69326513e1cebebe8e870c67 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Wed, 15 Nov 2023 21:15:17 +0100 Subject: [PATCH 4/5] elab_expr: Support part select for enums inside of structs Fixes #1033 Signed-off-by: Sylvain Munaut --- elab_expr.cc | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 1e8e2e502..0080d9971 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2486,8 +2486,8 @@ static NetExpr* check_for_struct_members(const LineInfo*li, } else if (const netenum_t*tmp_enum = dynamic_cast (member_type)) { - // If the element is an enum, then we don't have - // anything special to do. + // If the element is an enum, then we only need to check if + // there is a part select for it if (debug_elaborate) { cerr << li->get_fileline() << ": check_for_struct_members: " << "Tail element is an enum" << *tmp_enum @@ -2495,6 +2495,24 @@ static NetExpr* check_for_struct_members(const LineInfo*li, } struct_type = 0; + if (!member_comp.index.empty()) { + + if (member_comp.index.size() > 1) { + cerr << li->get_fileline() << ": error: " + << "Too many index expressions for enum member." << endl; + des->errors += 1; + return 0; + } + + long tail_off = 0; + unsigned long tail_wid = 0; + bool rc = calculate_part(li, des, scope, member_comp.index.back(), tail_off, tail_wid); + if (! rc) return 0; + + off += tail_off; + use_width = tail_wid; + } + } else if (const netvector_t*mem_vec = dynamic_cast(member_type)) { if (debug_elaborate) { From 483de9a75bd8bb3690e3a2f707f6bc7fc3ba9919 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Thu, 16 Nov 2023 09:25:38 +0100 Subject: [PATCH 5/5] ivtest: Add test for partselect on enum inside pack struct See issue #1033 Signed-off-by: Sylvain Munaut --- ivtest/ivltests/struct_enum_partsel.v | 24 +++++++++++++++++++++++ ivtest/regress-vvp.list | 1 + ivtest/vvp_tests/struct_enum_partsel.json | 5 +++++ 3 files changed, 30 insertions(+) create mode 100644 ivtest/ivltests/struct_enum_partsel.v create mode 100644 ivtest/vvp_tests/struct_enum_partsel.json diff --git a/ivtest/ivltests/struct_enum_partsel.v b/ivtest/ivltests/struct_enum_partsel.v new file mode 100644 index 000000000..b0aac672b --- /dev/null +++ b/ivtest/ivltests/struct_enum_partsel.v @@ -0,0 +1,24 @@ +module main; + + typedef enum logic [2:0] { + ENUM_VAL = 3'b110 + } enumtype; + + typedef struct packed { + enumtype e; + } structtype; + + structtype s; + + initial + begin + s.e = ENUM_VAL; + $display("s.e[2] = %d, s.e[1] = %d, s.e[0] = %d", s.e[2], s.e[1], s.e[0]); + if ((s.e[2] != 1'b1) || (s.e[1] != 1'b1) || (s.e[0] != 1'b0)) begin + $display("FAILED"); + $finish; + end + $display("PASSED"); + end + +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 1c5f24bb5..80c3adc3e 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -46,6 +46,7 @@ pr903 vvp_tests/pr903.json pr903-vlog95 vvp_tests/pr903-vlog95.json pv_wr_fn_vec2 vvp_tests/pv_wr_fn_vec2.json pv_wr_fn_vec4 vvp_tests/pv_wr_fn_vec4.json +struct_enum_partsel vvp_tests/struct_enum_partsel.json struct_field_left_right vvp_tests/struct_field_left_right.json struct_packed_write_read vvp_tests/struct_packed_write_read.json struct_packed_write_read2 vvp_tests/struct_packed_write_read2.json diff --git a/ivtest/vvp_tests/struct_enum_partsel.json b/ivtest/vvp_tests/struct_enum_partsel.json new file mode 100644 index 000000000..ac0bd0049 --- /dev/null +++ b/ivtest/vvp_tests/struct_enum_partsel.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "struct_enum_partsel.v", + "iverilog-args" : [ "-g2009" ] +}