diff --git a/elab_expr.cc b/elab_expr.cc index 3f41c32bb..f47ec86fb 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -3453,12 +3453,16 @@ NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope, if (sub == 0) return 0; - if (dynamic_cast(target_)) { - return cast_to_real(sub); - } - NetExpr*tmp = 0; - if (target_type_ && target_type_->packed()) { + if (dynamic_cast(target_type_)) { + return cast_to_real(sub); + } else if (dynamic_cast(target_type_)) { + if (base_->expr_type() == IVL_VT_STRING) + return sub; // no conversion + if (base_->expr_type() == IVL_VT_LOGIC || + base_->expr_type() == IVL_VT_BOOL) + return sub; // handled by the target as special cases + } else if (target_type_ && target_type_->packed()) { switch (target_type_->base_type()) { case IVL_VT_BOOL: tmp = cast_to_int2(sub, expr_width_); @@ -3483,15 +3487,6 @@ NetExpr* PECastType::elaborate_expr(Design*des, NetScope*scope, return pad_to_width(tmp, expr_wid, signed_flag_, *this, target_type_); } - if (dynamic_cast(target_)) { - if (base_->expr_type() == IVL_VT_STRING) - return sub; // no conversion - - if (base_->expr_type() == IVL_VT_LOGIC - || base_->expr_type() == IVL_VT_BOOL) - return sub; // handled by the target as special cases - } - cerr << get_fileline() << ": sorry: This cast operation is not yet supported." << endl; des->errors += 1; return 0; diff --git a/ivtest/ivltests/sv_cast_typedef.v b/ivtest/ivltests/sv_cast_typedef.v new file mode 100644 index 000000000..06811c28c --- /dev/null +++ b/ivtest/ivltests/sv_cast_typedef.v @@ -0,0 +1,42 @@ +// Check that type cast works as expected when using type identifiers. + +module test; + + typedef string T_S; + typedef real T_R; + typedef logic [15:0] T_V; + + string s; + real r; + logic [15:0] v; + + bit failed; + + `define check(expr, val) \ + if (expr != val) begin \ + $display("FAILED: %s, expected %0d, got %0d", `"expr`", val, expr); \ + failed = 1'b1; \ + end + + initial begin + v = "Hi"; + s = T_S'(v); + + `check(s, "Hi") + + v = 123; + r = T_R'(v); + + `check(r, 123) + + r = 1.23; + v = T_V'(r); + + `check(v, 16'd1) + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index 3561f1aa5..aa1b7517c 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -468,6 +468,7 @@ sv_cast_integer2 normal,-g2005-sv ivltests sv_cast_packed_array normal,-g2005-sv ivltests sv_cast_packed_struct normal,-g2005-sv ivltests sv_cast_string normal,-g2005-sv ivltests +sv_cast_typedef normal,-g2005-sv ivltests sv_class1 normal,-g2009 ivltests sv_class2 normal,-g2009 ivltests sv_class3 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index fde9fadc1..ae5fef303 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -286,6 +286,7 @@ plus_arg_string CE,-g2009 ivltests sformatf CE,-g2009 ivltests string_events CE,-g2009 ivltests string_index CE,-g2005-sv ivltests +sv_cast_typedef CE,-g2005-sv ivltests sv_macro CE,-g2009,-pallowsigned=1 ivltests sv_string1 CE,-g2009 ivltests sv_string2 CE,-g2009 ivltests