mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-25 10:05:33 +00:00
Resolve struct member multiple dimensions defined in stages with typedef
This commit is contained in:
parent
fab326d3e8
commit
f09ea16bd1
3 changed files with 62 additions and 55 deletions
|
@ -384,8 +384,7 @@ static int size_packed_struct(AstNode *snode, int base_offset)
|
|||
snode->range_right = base_offset;
|
||||
snode->range_left = base_offset + width - 1;
|
||||
snode->range_valid = true;
|
||||
if (snode->dimensions.empty())
|
||||
snode->dimensions.push_back({ 0, width, false });
|
||||
snode->dimensions.push_back({ 0, width, false });
|
||||
|
||||
return width;
|
||||
}
|
||||
|
@ -1439,57 +1438,16 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
|
|||
|
||||
case AST_STRUCT_ITEM:
|
||||
if (is_custom_type) {
|
||||
log_assert(children.size() == 1);
|
||||
log_assert(children.size() >= 1);
|
||||
log_assert(children[0]->type == AST_WIRETYPE);
|
||||
auto type_name = children[0]->str;
|
||||
if (!current_scope.count(type_name)) {
|
||||
log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", type_name.c_str());
|
||||
}
|
||||
AstNode *resolved_type_node = current_scope.at(type_name);
|
||||
if (resolved_type_node->type != AST_TYPEDEF)
|
||||
log_file_error(filename, location.first_line, "`%s' does not name a type\n", type_name.c_str());
|
||||
log_assert(resolved_type_node->children.size() == 1);
|
||||
AstNode *template_node = resolved_type_node->children[0];
|
||||
|
||||
// Ensure typedef itself is fully simplified
|
||||
while (template_node->simplify(const_fold, stage, width_hint, sign_hint)) {};
|
||||
|
||||
// Remove type reference
|
||||
delete children[0];
|
||||
children.pop_back();
|
||||
|
||||
switch (template_node->type) {
|
||||
case AST_WIRE:
|
||||
// Pretend it's just a wire in order to resolve the type.
|
||||
type = AST_WIRE;
|
||||
while (is_custom_type && simplify(const_fold, stage, width_hint, sign_hint)) {};
|
||||
if (type == AST_WIRE)
|
||||
type = AST_STRUCT_ITEM;
|
||||
break;
|
||||
case AST_STRUCT:
|
||||
case AST_UNION:
|
||||
type = template_node->type;
|
||||
break;
|
||||
default:
|
||||
log_file_error(filename, location.first_line, "Invalid type for struct member: %s", type2str(template_node->type).c_str());
|
||||
}
|
||||
|
||||
is_reg = template_node->is_reg;
|
||||
is_logic = template_node->is_logic;
|
||||
is_signed = template_node->is_signed;
|
||||
is_string = template_node->is_string;
|
||||
is_custom_type = template_node->is_custom_type;
|
||||
|
||||
range_valid = template_node->range_valid;
|
||||
range_swapped = template_node->range_swapped;
|
||||
range_left = template_node->range_left;
|
||||
range_right = template_node->range_right;
|
||||
|
||||
set_attribute(ID::wiretype, mkconst_str(resolved_type_node->str));
|
||||
|
||||
// Copy clones of children from template
|
||||
for (auto template_child : template_node->children) {
|
||||
children.push_back(template_child->clone());
|
||||
}
|
||||
|
||||
did_something = true;
|
||||
|
||||
}
|
||||
log_assert(!is_custom_type);
|
||||
break;
|
||||
|
@ -1963,14 +1921,16 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
|
|||
if (is_custom_type) {
|
||||
log_assert(children.size() >= 2);
|
||||
log_assert(children[1]->type == AST_WIRETYPE);
|
||||
// Pretend it's a wire in order to resolve the type in the code block above.
|
||||
|
||||
// Pretend it's just a wire in order to resolve the type in the code block above.
|
||||
AstNodeType param_type = type;
|
||||
type = AST_WIRE;
|
||||
AstNode *expr = children[0];
|
||||
children.erase(children.begin());
|
||||
while (simplify(const_fold, stage, width_hint, sign_hint)) {};
|
||||
while (is_custom_type && simplify(const_fold, stage, width_hint, sign_hint)) {};
|
||||
type = param_type;
|
||||
children.insert(children.begin(), expr);
|
||||
|
||||
if (children[1]->type == AST_MEMORY)
|
||||
input_error("unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
|
||||
fixup_hierarchy_flags();
|
||||
|
|
|
@ -1900,10 +1900,11 @@ struct_member_type: { astbuf1 = new AstNode(AST_STRUCT_ITEM); } member_type_toke
|
|||
;
|
||||
|
||||
member_type_token:
|
||||
member_type
|
||||
| hierarchical_type_id {
|
||||
addWiretypeNode($1, astbuf1);
|
||||
}
|
||||
member_type range_or_multirange {
|
||||
AstNode *range = checkRange(astbuf1, $2);
|
||||
if (range)
|
||||
astbuf1->children.push_back(range);
|
||||
}
|
||||
| {
|
||||
delete astbuf1;
|
||||
} struct_union {
|
||||
|
@ -1919,7 +1920,8 @@ member_type_token:
|
|||
;
|
||||
|
||||
member_type: type_atom type_signing
|
||||
| type_vec type_signing range_or_multirange { if ($3) astbuf1->children.push_back($3); }
|
||||
| type_vec type_signing
|
||||
| hierarchical_type_id { addWiretypeNode($1, astbuf1); }
|
||||
;
|
||||
|
||||
struct_var_list: struct_var
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue