systemverilog-plugin: fix accessing 2 dimensional packed array using single range Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc index e456857..c7ed80a 100644 --- a/systemverilog-plugin/UhdmAst.cc +++ b/systemverilog-plugin/UhdmAst.cc
@@ -606,22 +606,6 @@ } current_struct_elem = *struct_elem_it; - AST::AstNode *left = nullptr, *right = nullptr; - switch (current_struct_elem->type) { - case AST::AST_STRUCT_ITEM: - case AST::AST_STRUCT: - case AST::AST_UNION: - left = AST::AstNode::mkconst_int(current_struct_elem->range_left, true); - right = AST::AstNode::mkconst_int(current_struct_elem->range_right, true); - break; - default: - // Structs currently can only have AST_STRUCT, AST_STRUCT_ITEM, or AST_UNION. - log_file_error(current_struct_elem->filename, current_struct_elem->location.first_line, - "Accessing struct member of type %s is unsupported.\n", type2str(current_struct_elem->type).c_str()); - }; - - auto elem_size = - new AST::AstNode(AST::AST_ADD, new AST::AstNode(AST::AST_SUB, left->clone(), right->clone()), AST::AstNode::mkconst_int(1, true)); AST::AstNode *sub_dot = nullptr; AST::AstNode *struct_range = nullptr; @@ -639,6 +623,38 @@ struct_range = c; } } + AST::AstNode *left = nullptr, *right = nullptr; + switch (current_struct_elem->type) { + case AST::AST_STRUCT_ITEM: + left = AST::AstNode::mkconst_int(current_struct_elem->range_left, true); + right = AST::AstNode::mkconst_int(current_struct_elem->range_right, true); + break; + case AST::AST_STRUCT: + case AST::AST_UNION: + // TODO(krak): add proper support for accessing struct/union elements + // with multirange + // Currently support only special access to 2 dimensional packed element + // when selecting single range + if (struct_range && current_struct_elem->multirange_swapped.size() == 2 /* 2 dimensional */) { + // get element size in number of bits + const int single_elem_size = current_struct_elem->children.front()->range_left + 1; + left = AST::AstNode::mkconst_int(single_elem_size * current_struct_elem->multirange_dimensions.back(), true); + right = + AST::AstNode::mkconst_int(current_struct_elem->children.back()->range_right * current_struct_elem->multirange_dimensions.back(), true); + } else { + left = AST::AstNode::mkconst_int(current_struct_elem->children.front()->range_left, true); + right = AST::AstNode::mkconst_int(current_struct_elem->children.back()->range_right, true); + } + break; + default: + // Structs currently can only have AST_STRUCT, AST_STRUCT_ITEM, or AST_UNION. + log_file_error(current_struct_elem->filename, current_struct_elem->location.first_line, + "Accessing struct member of type %s is unsupported.\n", type2str(current_struct_elem->type).c_str()); + }; + + auto elem_size = + new AST::AstNode(AST::AST_ADD, new AST::AstNode(AST::AST_SUB, left->clone(), right->clone()), AST::AstNode::mkconst_int(1, true)); + if (sub_dot) { // First select correct element in first struct delete left;