aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ast
diff options
context:
space:
mode:
authorKamil Rakoczy <krakoczy@antmicro.com>2022-02-14 14:34:20 +0100
committerGitHub <noreply@github.com>2022-02-14 14:34:20 +0100
commit68c67c40ec75b192f4f1be9711afe0df8973e797 (patch)
treef67834903e40ae61b39a04555ff1b96763c59cd0 /frontends/ast
parent59738c09beb3ba43a693b77eb4545122a99df7d2 (diff)
downloadyosys-68c67c40ec75b192f4f1be9711afe0df8973e797.tar.gz
yosys-68c67c40ec75b192f4f1be9711afe0df8973e797.tar.bz2
yosys-68c67c40ec75b192f4f1be9711afe0df8973e797.zip
Fix access to whole sub-structs (#3086)
* Add support for accessing whole struct * Update tests Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
Diffstat (limited to 'frontends/ast')
-rw-r--r--frontends/ast/genrtlil.cc2
-rw-r--r--frontends/ast/simplify.cc22
2 files changed, 18 insertions, 6 deletions
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 4c25287ad..020b4e5e8 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -877,7 +877,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1;
if (children.size() > 1)
range = children[1];
- } else if (id_ast->type == AST_STRUCT_ITEM) {
+ } else if (id_ast->type == AST_STRUCT_ITEM || id_ast->type == AST_STRUCT) {
AstNode *tmp_range = make_struct_member_range(this, id_ast);
this_width = tmp_range->range_left - tmp_range->range_right + 1;
delete tmp_range;
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 000877612..565025d3a 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -307,6 +307,10 @@ static int size_packed_struct(AstNode *snode, int base_offset)
if (node->type == AST_STRUCT || node->type == AST_UNION) {
// embedded struct or union
width = size_packed_struct(node, base_offset + offset);
+ // set range of struct
+ node->range_right = base_offset + offset;
+ node->range_left = base_offset + offset + width - 1;
+ node->range_valid = true;
}
else {
log_assert(node->type == AST_STRUCT_ITEM);
@@ -493,14 +497,12 @@ static void add_members_to_scope(AstNode *snode, std::string name)
// in case later referenced in assignments
log_assert(snode->type==AST_STRUCT || snode->type==AST_UNION);
for (auto *node : snode->children) {
+ auto member_name = name + "." + node->str;
+ current_scope[member_name] = node;
if (node->type != AST_STRUCT_ITEM) {
// embedded struct or union
add_members_to_scope(node, name + "." + node->str);
}
- else {
- auto member_name = name + "." + node->str;
- current_scope[member_name] = node;
- }
}
}
@@ -1341,6 +1343,16 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
case AST_PARAMETER:
case AST_LOCALPARAM:
+ // if parameter is implicit type which is the typename of a struct or union,
+ // save information about struct in wiretype attribute
+ if (children[0]->type == AST_IDENTIFIER && current_scope.count(children[0]->str) > 0) {
+ auto item_node = current_scope[children[0]->str];
+ if (item_node->type == AST_STRUCT || item_node->type == AST_UNION) {
+ attributes[ID::wiretype] = item_node->clone();
+ size_packed_struct(attributes[ID::wiretype], 0);
+ add_members_to_scope(attributes[ID::wiretype], str);
+ }
+ }
while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true)
did_something = true;
children[0]->detectSignWidth(width_hint, sign_hint);
@@ -2018,7 +2030,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (name_has_dot(str, sname)) {
if (current_scope.count(str) > 0) {
auto item_node = current_scope[str];
- if (item_node->type == AST_STRUCT_ITEM) {
+ if (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT) {
// structure member, rewrite this node to reference the packed struct wire
auto range = make_struct_member_range(this, item_node);
newNode = new AstNode(AST_IDENTIFIER, range);