// resolve typedefs
if (type == AST_TYPEDEF) {
log_assert(children.size() == 1);
- log_assert(children[0]->type == AST_WIRE);
- while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
+ log_assert(children[0]->type == AST_WIRE || children[0]->type == AST_MEMORY);
+ while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {
+ did_something = true;
+ };
log_assert(!children[0]->is_custom_type);
}
// Ensure typedef itself is fully simplified
while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
+ type = templ->type;
is_reg = templ->is_reg;
is_logic = templ->is_logic;
is_signed = templ->is_signed;
range_right = templ->range_right;
for (auto template_child : templ->children)
children.push_back(template_child->clone());
+ did_something = true;
}
log_assert(!is_custom_type);
}
// Ensure typedef itself is fully simplified
while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
+ if (templ->type == AST_MEMORY)
+ log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
is_signed = templ->is_signed;
is_string = templ->is_string;
is_custom_type = templ->is_custom_type;
range_right = templ->range_right;
for (auto template_child : templ->children)
children.push_back(template_child->clone());
+ did_something = true;
}
log_assert(!is_custom_type);
}
uint32_t children_flags = 0;
int lhs_children_counter = 0;
+ if (type == AST_TYPEDEF)
+ return; // don't touch content of typedefs
+
if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
{
// mark all memories that are used in a complex expression on the left side of an assignment
if (type == AST_FUNCTION || type == AST_TASK)
return false;
+ if (type == AST_TYPEDEF)
+ return false;
+
if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
{
log_assert(children[0]->type == AST_CONSTANT);
};
typedef_decl:
- TOK_TYPEDEF wire_type range TOK_ID ';' {
+ TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
astbuf1 = $2;
astbuf2 = $3;
if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
if (astbuf2)
astbuf1->children.push_back(astbuf2);
+
+ if ($5 != NULL) {
+ if (!astbuf2) {
+ AstNode *rng = new AstNode(AST_RANGE);
+ rng->children.push_back(AstNode::mkconst_int(0, true));
+ rng->children.push_back(AstNode::mkconst_int(0, true));
+ astbuf1->children.push_back(rng);
+ }
+ astbuf1->type = AST_MEMORY;
+ auto *rangeNode = $5;
+ if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
+ // SV array size [n], rewrite as [n-1:0]
+ rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
+ rangeNode->children.push_back(AstNode::mkconst_int(0, false));
+ }
+ astbuf1->children.push_back(rangeNode);
+ }
+
ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
ast_stack.back()->children.back()->str = *$4;
};