diff --git a/netmisc.cc b/netmisc.cc index 6bb216e85..3a544f681 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -184,7 +184,15 @@ NetNet* cast_to_real(Design*des, NetScope*scope, NetNet*src) NetExpr* cast_to_int2(NetExpr*expr) { - NetECast*cast = new NetECast('2', expr, expr->expr_width(), + // Special case: The expression is alreadt BOOL + if (expr->expr_type() == IVL_VT_BOOL) + return expr; + + unsigned use_width = expr->expr_width(); + if (expr->expr_type() == IVL_VT_REAL) + use_width = 64; + + NetECast*cast = new NetECast('2', expr, use_width, expr->has_sign()); cast->set_line(*expr); return cast; diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 8d10e52fb..e79043543 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -3118,19 +3118,37 @@ static struct vector_info draw_unary_expr(ivl_expr_t expr, unsigned wid) local_count += 1; break; - case '2': /* Cast logic to bool */ - assert(ivl_expr_value(sub) == IVL_VT_LOGIC); - res = draw_eval_expr_wid(sub, wid, 0); + case '2': /* Cast expression to bool */ + switch (ivl_expr_value(sub)) { + case IVL_VT_BOOL: + res = draw_eval_expr_wid(sub, wid, 0); + break; - /* Handle special case that value is 0 or 1. */ - if (res.base == 0 || res.base == 1) + case IVL_VT_LOGIC: + res = draw_eval_expr_wid(sub, wid, 0); + + /* Handle special case that value is 0 or 1. */ + if (res.base == 0 || res.base == 1) + break; + if (res.base == 2 || res.base == 2) { + res.base = 0; + break; + } + + fprintf(vvp_out, " %%cast2 %d, %d, %u;\n", res.base, res.base, res.wid); break; - if (res.base == 2 || res.base == 2) { - res.base = 0; + + case IVL_VT_REAL: + word = draw_eval_real(sub); + res.base = allocate_vector(wid); + res.wid = wid; + fprintf(vvp_out, " %%cvt/vr %d, %d, %u;\n", res.base, word, wid); + clr_word(word); break; + + default: + assert(0); } - - fprintf(vvp_out, " %%cast2 %d, %d, %u;\n", res.base, res.base, res.wid); break; case 'i': /* Cast a real value to an integer. */