From 053453c645f9ec539e2cf5d86f710458d56ed124 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 16 Jan 2022 10:08:29 +0100 Subject: [PATCH] Add support for explicit cast to enum Assigning a value to an enum signal that is not of the same type as the enum requires an explicit cast. To support this attach the type of a type cast to the resulting expression. This allows the assignment elaboration to confirm that value has been explicitly cast to the right type. Also handle the case where the value is a constant. In this case create a NetEConstEnum instead of a NetEConst as the resulting expression. Signed-off-by: Lars-Peter Clausen --- elab_expr.cc | 2 +- netmisc.h | 6 +++--- pad_to_width.cc | 15 +++++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index d3c89fe23..a6cb6b447 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3447,7 +3447,7 @@ NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope, // the signedness pushed down from the main expression. tmp = cast_to_width(sub, expr_width_, sub->has_sign(), *this); } - return pad_to_width(tmp, expr_wid, signed_flag_, *this); + return pad_to_width(tmp, expr_wid, signed_flag_, *this, target_type_); } if (dynamic_cast(target_)) { diff --git a/netmisc.h b/netmisc.h index 4a7d23f8a..17f3d20b9 100644 --- a/netmisc.h +++ b/netmisc.h @@ -161,13 +161,13 @@ inline NetScope* symbol_search(const LineInfo*li, * signed_flag. */ extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid, bool signed_flag, - const LineInfo&info); + const LineInfo&info, ivl_type_t use_type = 0); /* * This version determines the extension method from the base expression type. */ -inline NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info) +inline NetExpr*pad_to_width(NetExpr*expr, unsigned wid, const LineInfo&info, ivl_type_t use_type = 0) { - return pad_to_width(expr, wid, expr->has_sign(), info); + return pad_to_width(expr, wid, expr->has_sign(), info, use_type); } /* diff --git a/pad_to_width.cc b/pad_to_width.cc index 32db9e6c4..5ec66a862 100644 --- a/pad_to_width.cc +++ b/pad_to_width.cc @@ -19,15 +19,16 @@ # include "config.h" +# include "netenum.h" # include "netlist.h" # include "netvector.h" # include "netmisc.h" NetExpr*pad_to_width(NetExpr*expr, unsigned wid, bool signed_flag, - const LineInfo&info) + const LineInfo&info, ivl_type_t use_type) { - if (wid <= expr->expr_width()) { + if (wid <= expr->expr_width() && !use_type) { expr->cast_signed(signed_flag); return expr; } @@ -38,13 +39,19 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid, bool signed_flag, verinum oval = tmp->value(); oval.has_sign(signed_flag); oval = pad_to_width(oval, wid); - tmp = new NetEConst(oval); + if (const netenum_t *enum_type = dynamic_cast(use_type)) { + // The name of the enum is set to here, but the name is + // only used in debugging output, so this is ok + tmp = new NetEConstEnum(perm_string(), enum_type, oval); + } else { + tmp = new NetEConst(oval); + } tmp->set_line(info); delete expr; return tmp; } - NetESelect*tmp = new NetESelect(expr, 0, wid); + NetESelect*tmp = new NetESelect(expr, 0, wid, use_type); tmp->cast_signed(signed_flag); tmp->set_line(info); return tmp;