aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/ast
diff options
context:
space:
mode:
authorZachary Snow <zach@zachjs.com>2021-06-22 10:39:57 -0400
committerZachary Snow <zachary.j.snow@gmail.com>2021-07-15 11:57:20 -0400
commita9c8ca21d583c58a38931389f90bbaae0caec0d6 (patch)
treeeab021de70957cf08a44d296fbf63b29e3a3e9e7 /frontends/ast
parent1aab608cffa19332dc5cf722def7413b16f5ee54 (diff)
downloadyosys-a9c8ca21d583c58a38931389f90bbaae0caec0d6.tar.gz
yosys-a9c8ca21d583c58a38931389f90bbaae0caec0d6.tar.bz2
yosys-a9c8ca21d583c58a38931389f90bbaae0caec0d6.zip
sv: fix two struct access bugs
- preserve signedness of struct members - fix initial width detection of struct members (e.g., in case expressions)
Diffstat (limited to 'frontends/ast')
-rw-r--r--frontends/ast/ast.h3
-rw-r--r--frontends/ast/genrtlil.cc4
-rw-r--r--frontends/ast/simplify.cc4
3 files changed, 10 insertions, 1 deletions
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 2bda8fa92..60c7de32d 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -370,6 +370,9 @@ namespace AST
// Helper for setting the src attribute.
void set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast);
+
+ // struct helper exposed from simplify for genrtlil
+ AstNode *make_struct_member_range(AstNode *node, AstNode *member_node);
}
namespace AST_INTERNAL
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index e6f7b30c1..29d0bddef 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -812,6 +812,10 @@ 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) {
+ AstNode *tmp_range = make_struct_member_range(this, id_ast);
+ this_width = tmp_range->range_left - tmp_range->range_right + 1;
+ delete tmp_range;
} else
log_file_error(filename, location.first_line, "Failed to detect width for identifier %s!\n", str.c_str());
if (range) {
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 695fc429d..5845c0501 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -456,7 +456,7 @@ static AstNode *slice_range(AstNode *rnode, AstNode *snode)
}
-static AstNode *make_struct_member_range(AstNode *node, AstNode *member_node)
+AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node)
{
// Work out the range in the packed array that corresponds to a struct member
// taking into account any range operations applicable to the current node
@@ -1693,6 +1693,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
newNode = new AstNode(AST_IDENTIFIER, range);
newNode->str = sname;
newNode->basic_prep = true;
+ if (item_node->is_signed)
+ newNode = new AstNode(AST_TO_SIGNED, newNode);
goto apply_newNode;
}
}