Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added cast to type support #4284

Merged
merged 5 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion frontends/ast/ast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,10 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const
fprintf(f, ";\n");
break;

case AST_WIRETYPE:
fprintf(f, "%s", id2vl(str).c_str());
break;

case AST_MEMORY:
fprintf(f, "%s" "memory", indent.c_str());
if (is_signed)
Expand Down Expand Up @@ -690,7 +694,17 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const
break;

case AST_CAST_SIZE:
children[0]->dumpVlog(f, "");
switch (children[0]->type)
{
case AST_WIRE:
if (children[0]->children.size() > 0)
children[0]->children[0]->dumpVlog(f, "");
else
fprintf(f, "%d'", children[0]->range_left - children[0]->range_right + 1);
break;
default:
children[0]->dumpVlog(f, "");
}
fprintf(f, "'(");
children[1]->dumpVlog(f, "");
fprintf(f, ")");
Expand Down
60 changes: 59 additions & 1 deletion frontends/ast/simplify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1500,11 +1500,69 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin
}
break;

case AST_CAST_SIZE: {
int width = 1;
AstNode *node;
AstNode *child = children[0];

if (child->type == AST_WIRE) {
if (child->children.size() == 0) {
// Base type (e.g., int)
width = child->range_left - child->range_right +1;
node = mkconst_int(width, child->is_signed);
} else {
// User defined type
log_assert(child->children[0]->type == AST_WIRETYPE);

const std::string &type_name = child->children[0]->str;
if (!current_scope.count(type_name))
input_error("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)
input_error("`%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)) {};

switch (template_node->type)
{
case AST_WIRE: {
if (template_node->children.size() > 0 && template_node->children[0]->type == AST_RANGE)
width = range_width(this, template_node->children[0]);
child->delete_children();
node = mkconst_int(width, true);
break;
}

case AST_STRUCT:
case AST_UNION: {
child->delete_children();
width = size_packed_struct(template_node, 0);
node = mkconst_int(width, false);
break;
}

default:
log_error("Don't know how to translate static cast of type %s\n", type2str(template_node->type).c_str());
}
}

delete child;
children.erase(children.begin());
children.insert(children.begin(), node);
}

detect_width_simple = true;
children_are_self_determined = true;
break;
}

case AST_TO_BITS:
case AST_TO_SIGNED:
case AST_TO_UNSIGNED:
case AST_SELFSZ:
case AST_CAST_SIZE:
case AST_CONCAT:
case AST_REPLICATE:
case AST_REDUCE_AND:
Expand Down
6 changes: 6 additions & 0 deletions frontends/verilog/verilog_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -3506,6 +3506,12 @@ basic_expr:
$$ = new AstNode(AST_CAST_SIZE, $1, $4);
SET_AST_NODE_LOC($$, @1, @4);
} |
typedef_base_type OP_CAST '(' expr ')' {
if (!sv_mode)
frontend_verilog_yyerror("Static cast is only supported in SystemVerilog mode.");
$$ = new AstNode(AST_CAST_SIZE, $1, $4);
SET_AST_NODE_LOC($$, @1, @4);
} |
'(' expr '=' expr ')' {
ensureAsgnExprAllowed();
AstNode *node = new AstNode(AST_ASSIGN_EQ, $2, $4);
Expand Down
Loading
Loading