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 <lars@metafoo.de>
This commit is contained in:
parent
9b7c99b8a8
commit
053453c645
|
|
@ -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<const string_type_t*>(target_)) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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<const netenum_t *>(use_type)) {
|
||||
// The name of the enum is set to <nil> 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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue