From c96a6bfa0917aeb39a2ee4103b4836711c2c9ad2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 20 Mar 2022 14:44:18 +0100 Subject: [PATCH 1/2] Elaborate base type of array types in the right scope The base type of an array type needs to be elaborated in the scope where the array type is declared. At the moment it is elaborated in the scope where the signal is declared, which can cause incorrect results. E.g. in the example below the width of the array base type would be 4 instead of 8. ``` localparam A = 8; typedef reg [A-1:0] T[1:0]; module test; localparam A = 4; T x; endmodule ``` If an unpacked array type is specified use the scope of the array type as the default scope for the base type. Note that the base type can still be a typedef in a different scope than the array scope, but we need to start searching for it in the array scope. Signed-off-by: Lars-Peter Clausen --- elab_sig.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/elab_sig.cc b/elab_sig.cc index f472c7595..05d3f0630 100644 --- a/elab_sig.cc +++ b/elab_sig.cc @@ -1029,9 +1029,13 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const unsigned wid = 1; vectorpacked_dimensions; - NetScope*base_type_scope = scope; + NetScope*array_type_scope = scope; + if (uarray_type_ && !uarray_type_->name.nil()) + array_type_scope = array_type_scope->find_typedef_scope(des, uarray_type_); + + NetScope*base_type_scope = array_type_scope; if (set_data_type_ && !set_data_type_->name.nil()) - base_type_scope = scope->find_typedef_scope(des, set_data_type_); + base_type_scope = base_type_scope->find_typedef_scope(des, set_data_type_); des->errors += error_cnt_; @@ -1142,10 +1146,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const listunpacked_dimensions; netdarray_t*netdarray = 0; - NetScope*array_type_scope = scope; - if (uarray_type_ && !uarray_type_->name.nil()) - array_type_scope = scope->find_typedef_scope(des, uarray_type_); - for (list::const_iterator cur = unpacked_.begin() ; cur != unpacked_.end() ; ++cur) { PExpr*use_lidx = cur->first; @@ -1155,7 +1155,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const // dimensions, then turn this into a dynamic array and // put all the packed dimensions there. if (use_lidx==0 && use_ridx==0) { - ivl_type_t base_type = elaborate_darray_type(des, scope, + ivl_type_t base_type = elaborate_darray_type(des, + array_type_scope, "Dynamic array", packed_dimensions); packed_dimensions.clear(); @@ -1167,7 +1168,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const // Special case: Detect the mark for a QUEUE // declaration, which is the dimensions [null:max_idx]. if (dynamic_cast(use_lidx)) { - ivl_type_t base_type = elaborate_darray_type(des, scope, + ivl_type_t base_type = elaborate_darray_type(des, + array_type_scope, "Queue", packed_dimensions); packed_dimensions.clear(); @@ -1285,7 +1287,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const sig = new NetNet(scope, name_, wtype, netdarray); } else { - ivl_type_t use_type = elaborate_type(des, scope, + ivl_type_t use_type = elaborate_type(des, array_type_scope, packed_dimensions); if (debug_elaborate) { From 1a95dafc8d6f4cdb1142081486017f449471c8c0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 24 Mar 2022 10:06:43 +0100 Subject: [PATCH 2/2] Add regression tests array base type elaboration scope Check that for typedefs of array, dynamic array and queue types the base type is elaborated in the right scope. There are separate tests for vector base type and other base types since these take different paths internally. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_typedef_array_base1.v | 22 ++++++++++++++++++ ivtest/ivltests/sv_typedef_array_base2.v | 24 ++++++++++++++++++++ ivtest/ivltests/sv_typedef_array_base3.v | 24 ++++++++++++++++++++ ivtest/ivltests/sv_typedef_array_base4.v | 27 +++++++++++++++++++++++ ivtest/ivltests/sv_typedef_darray_base1.v | 23 +++++++++++++++++++ ivtest/ivltests/sv_typedef_darray_base2.v | 25 +++++++++++++++++++++ ivtest/ivltests/sv_typedef_darray_base3.v | 26 ++++++++++++++++++++++ ivtest/ivltests/sv_typedef_darray_base4.v | 27 +++++++++++++++++++++++ ivtest/ivltests/sv_typedef_queue_base1.v | 22 ++++++++++++++++++ ivtest/ivltests/sv_typedef_queue_base2.v | 24 ++++++++++++++++++++ ivtest/ivltests/sv_typedef_queue_base3.v | 24 ++++++++++++++++++++ ivtest/ivltests/sv_typedef_queue_base4.v | 27 +++++++++++++++++++++++ ivtest/regress-sv.list | 12 ++++++++++ ivtest/regress-vlog95.list | 8 +++++++ 14 files changed, 315 insertions(+) create mode 100644 ivtest/ivltests/sv_typedef_array_base1.v create mode 100644 ivtest/ivltests/sv_typedef_array_base2.v create mode 100644 ivtest/ivltests/sv_typedef_array_base3.v create mode 100644 ivtest/ivltests/sv_typedef_array_base4.v create mode 100644 ivtest/ivltests/sv_typedef_darray_base1.v create mode 100644 ivtest/ivltests/sv_typedef_darray_base2.v create mode 100644 ivtest/ivltests/sv_typedef_darray_base3.v create mode 100644 ivtest/ivltests/sv_typedef_darray_base4.v create mode 100644 ivtest/ivltests/sv_typedef_queue_base1.v create mode 100644 ivtest/ivltests/sv_typedef_queue_base2.v create mode 100644 ivtest/ivltests/sv_typedef_queue_base3.v create mode 100644 ivtest/ivltests/sv_typedef_queue_base4.v diff --git a/ivtest/ivltests/sv_typedef_array_base1.v b/ivtest/ivltests/sv_typedef_array_base1.v new file mode 100644 index 000000000..02d40b851 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_array_base1.v @@ -0,0 +1,22 @@ +// Check that a vector base typeof an array type is evaluated in the scope where +// the array type is declared. + +localparam A = 8; + +typedef logic [A-1:0] T[1:0]; + +module test; + localparam A = 4; + + T x; + + initial begin + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_array_base2.v b/ivtest/ivltests/sv_typedef_array_base2.v new file mode 100644 index 000000000..52adc200b --- /dev/null +++ b/ivtest/ivltests/sv_typedef_array_base2.v @@ -0,0 +1,24 @@ +// Check that a complex base type (like a struct) of an array type is evaluated +// in the scope where the array type is declared. + +localparam A = 8; + +typedef struct packed { + logic [A-1:0] x; +} T[1:0]; + +module test; + localparam A = 4; + + T x; + + initial begin + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_array_base3.v b/ivtest/ivltests/sv_typedef_array_base3.v new file mode 100644 index 000000000..1df783347 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_array_base3.v @@ -0,0 +1,24 @@ +// Check that a vector base type of an array type gets evaluated in the right +// scope if the base type is defined in a different scope than the array type. + +localparam A = 8; + +typedef logic [A-1:0] Base; + +module test; + localparam A = 4; + + typedef Base T[1:0]; + + T x; + + initial begin + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_array_base4.v b/ivtest/ivltests/sv_typedef_array_base4.v new file mode 100644 index 000000000..e536512ad --- /dev/null +++ b/ivtest/ivltests/sv_typedef_array_base4.v @@ -0,0 +1,27 @@ +// Check that a complex base type (like a struct) of an array type gets +// evaluated in the right scope if the base type is defined in a different scope +// than the array type. + +localparam A = 8; + +typedef struct packed { + logic [A-1:0] x; +} Base; + +module test; + localparam A = 4; + + typedef Base T[1:0]; + + T x; + + initial begin + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_darray_base1.v b/ivtest/ivltests/sv_typedef_darray_base1.v new file mode 100644 index 000000000..24713e4f2 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_darray_base1.v @@ -0,0 +1,23 @@ +// Check that a vector base typeof a dynamic array type is evaluated in the +// scope where the array type is declared. + +localparam A = 8; + +typedef logic [A-1:0] T[]; + +module test; + localparam A = 4; + + T x; + + initial begin + x = new [1]; + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_darray_base2.v b/ivtest/ivltests/sv_typedef_darray_base2.v new file mode 100644 index 000000000..7bef82475 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_darray_base2.v @@ -0,0 +1,25 @@ +// Check that a complex base type (like a packed array) of a dynamic array type +// is evaluated in the scope where the array type is declared. + +localparam A = 8; + +// Use type identifier for the base to force packed array +typedef logic l; +typedef l [A-1:0] T[]; + +module test; + localparam A = 4; + + T x; + + initial begin + x = new [1]; + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_darray_base3.v b/ivtest/ivltests/sv_typedef_darray_base3.v new file mode 100644 index 000000000..fff7e27e8 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_darray_base3.v @@ -0,0 +1,26 @@ +// Check that a vector base type of a dynamic array type gets evaluated in the +// right scope if the base type is defined in a different scope than the array +// type. + +localparam A = 8; + +typedef logic [A-1:0] Base; + +module test; + localparam A = 4; + + typedef Base T[]; + + T x; + + initial begin + x = new [1]; + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_darray_base4.v b/ivtest/ivltests/sv_typedef_darray_base4.v new file mode 100644 index 000000000..943bfe19f --- /dev/null +++ b/ivtest/ivltests/sv_typedef_darray_base4.v @@ -0,0 +1,27 @@ +// Check that a complex base type (like a struct) of a dynamic array type gets +// evaluated in the right scope if the base type is defined in a different scope +// than the array type. + +localparam A = 8; + +// Use type identifier for the base to force packed array +typedef logic l; +typedef l [A-1:0] Base; + +module test; + localparam A = 4; + + typedef Base T[]; + T x; + + initial begin + x = new [1]; + x[0] = 8'hff; + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_queue_base1.v b/ivtest/ivltests/sv_typedef_queue_base1.v new file mode 100644 index 000000000..3df26e285 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_queue_base1.v @@ -0,0 +1,22 @@ +// Check that a vector base typeof a queue type is evaluated in the scope where +// the array type is declared. + +localparam A = 8; + +typedef logic [A-1:0] T[$]; + +module test; + localparam A = 4; + + T x; + + initial begin + x.push_back(8'hff); + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_queue_base2.v b/ivtest/ivltests/sv_typedef_queue_base2.v new file mode 100644 index 000000000..acdbc30b8 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_queue_base2.v @@ -0,0 +1,24 @@ +// Check that a complex base type (like a packed array) of a queue type is +// evaluated in the scope where the array type is declared. + +localparam A = 8; + +// Use type identifier for the base to force packed array +typedef logic l; +typedef l [A-1:0] T[$]; + +module test; + localparam A = 4; + + T x; + + initial begin + x.push_back(8'hff); + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_queue_base3.v b/ivtest/ivltests/sv_typedef_queue_base3.v new file mode 100644 index 000000000..6a611007d --- /dev/null +++ b/ivtest/ivltests/sv_typedef_queue_base3.v @@ -0,0 +1,24 @@ +// Check that a vector base type of a queue type gets evaluated in the right +// scope if the base type is defined in a different scope than the array type. + +localparam A = 8; + +typedef logic [A-1:0] Base; + +module test; + localparam A = 4; + + typedef Base T[$]; + + T x; + + initial begin + x.push_back(8'hff); + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_typedef_queue_base4.v b/ivtest/ivltests/sv_typedef_queue_base4.v new file mode 100644 index 000000000..38b3f6fe5 --- /dev/null +++ b/ivtest/ivltests/sv_typedef_queue_base4.v @@ -0,0 +1,27 @@ +// Check that a complex base type (like a packed array) of a queue type gets +// evaluated in the right scope if the base type is defined in a different scope +// than the array type. + +localparam A = 8; + +// Use type identifier for the base to force packed array +typedef logic l; +typedef l [A-1:0] Base; + +module test; + localparam A = 4; + + typedef Base T[$]; + + T x; + + initial begin + x.push_back(8'hff); + if (x[0] === 8'hff) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 8312bd6b3..a55e4a3f1 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -589,6 +589,18 @@ sv_timeunit_prec_fail2 CE,-g2009,-u,\ ./ivltests/sv_timeunit_prec_fail2a.v,\ ./ivltests/sv_timeunit_prec_fail2b.v,\ ./ivltests/sv_timeunit_prec_fail2c.v, ivltests gold=sv_timeunit_prec_fail2.gold +sv_typedef_array_base1 normal,-g2009 ivltests +sv_typedef_array_base2 normal,-g2009 ivltests +sv_typedef_array_base3 normal,-g2009 ivltests +sv_typedef_array_base4 normal,-g2009 ivltests +sv_typedef_darray_base1 normal,-g2009 ivltests +sv_typedef_darray_base2 normal,-g2009 ivltests +sv_typedef_darray_base3 normal,-g2009 ivltests +sv_typedef_darray_base4 normal,-g2009 ivltests +sv_typedef_queue_base1 normal,-g2009 ivltests +sv_typedef_queue_base2 normal,-g2009 ivltests +sv_typedef_queue_base3 normal,-g2009 ivltests +sv_typedef_queue_base4 normal,-g2009 ivltests sv_typedef_scope1 normal,-g2009 ivltests sv_typedef_scope2 normal,-g2009 ivltests sv_typedef_scope3 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index f5944b788..07b76e421 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -439,6 +439,14 @@ pr3390385b CE,-g2009 ivltests # ++ pr3390385c CE,-g2009 ivltests # ++ pr3390385d CE,-g2009 ivltests # ++ pr3462145 CE,-g2009 ivltests # ++ +sv_typedef_darray_base1 CE,-g2009 ivltests # Dyanmic array +sv_typedef_darray_base2 CE,-g2009 ivltests # Dyanmic array +sv_typedef_darray_base3 CE,-g2009 ivltests # Dyanmic array +sv_typedef_darray_base4 CE,-g2009 ivltests # Dyanmic array +sv_typedef_queue_base1 CE,-g2009 ivltests # queue +sv_typedef_queue_base2 CE,-g2009 ivltests # queue +sv_typedef_queue_base3 CE,-g2009 ivltests # queue +sv_typedef_queue_base4 CE,-g2009 ivltests # queue wait_fork CE,-g2009 ivltests # wait fork and join_* wild_cmp_err CE,-g2009 ivltests # ==?/!=? wild_cmp_err2 CE,-g2009 ivltests # ==?/!=?