From c96a6bfa0917aeb39a2ee4103b4836711c2c9ad2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 20 Mar 2022 14:44:18 +0100 Subject: [PATCH] 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) {