From c066e2d15c2ed611af20742c74378aa7058105f2 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Wed, 11 Sep 2019 22:08:46 +0100 Subject: [PATCH] Properly implement casts from strings and dynamic arrays to vectors. As discussed on iverilog-devel (2018-03-09), the existing implementation (using Icarus-specific vpi functions) only worked with assignments to simple variables, and could not be easily modified to work more generally. So use the new vvp instructions added in the previous two commits. --- netmisc.cc | 4 ++-- tgt-vvp/eval_vec4.c | 32 +++++++++++++++++++++++++++----- tgt-vvp/stmt_assign.c | 33 +-------------------------------- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/netmisc.cc b/netmisc.cc index 427fd56e2..74d35e501 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2001-2019 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -158,7 +158,7 @@ NetExpr* cast_to_int2(NetExpr*expr, unsigned width) NetExpr* cast_to_int4(NetExpr*expr, unsigned width) { // Special case: The expression is already LOGIC or BOOL - if (expr->expr_type() != IVL_VT_REAL) + if (expr->expr_type() == IVL_VT_LOGIC || expr->expr_type() == IVL_VT_BOOL) return expr; if (debug_elaborate) diff --git a/tgt-vvp/eval_vec4.c b/tgt-vvp/eval_vec4.c index 4972f4b05..899ee478b 100644 --- a/tgt-vvp/eval_vec4.c +++ b/tgt-vvp/eval_vec4.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 Stephen Williams (steve@icarus.com) + * Copyright (c) 2013-2019 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -1255,10 +1255,24 @@ static void draw_unary_vec4(ivl_expr_t expr) local_count += 1; break; - case 'v': /* Cast real to vec4 */ - assert(ivl_expr_value(sub) == IVL_VT_REAL); - draw_eval_real(sub); - fprintf(vvp_out, " %%cvt/vr %u;\n", ivl_expr_width(expr)); + case 'v': /* Cast expression to vec4 */ + switch (ivl_expr_value(sub)) { + case IVL_VT_REAL: + draw_eval_real(sub); + fprintf(vvp_out, " %%cvt/vr %u;\n", ivl_expr_width(expr)); + break; + case IVL_VT_STRING: + draw_eval_string(sub); + fprintf(vvp_out, " %%cast/vec4/str %u;\n", ivl_expr_width(expr)); + break; + case IVL_VT_DARRAY: + draw_eval_object(sub); + fprintf(vvp_out, " %%cast/vec4/dar %u;\n", ivl_expr_width(expr)); + break; + default: + assert(0); + break; + } break; case '2': /* Cast expression to bool */ @@ -1276,6 +1290,14 @@ static void draw_unary_vec4(ivl_expr_t expr) draw_eval_real(sub); fprintf(vvp_out, " %%cvt/vr %u;\n", ivl_expr_width(expr)); break; + case IVL_VT_STRING: + draw_eval_string(sub); + fprintf(vvp_out, " %%cast/vec4/str %u;\n", ivl_expr_width(expr)); + break; + case IVL_VT_DARRAY: + draw_eval_object(sub); + fprintf(vvp_out, " %%cast/vec2/dar %u;\n", ivl_expr_width(expr)); + break; default: assert(0); break; diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index f10291e20..8ad27c450 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 Stephen Williams (steve@icarus.com) + * Copyright (c) 2011-2019 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU @@ -515,37 +515,6 @@ static int show_stmt_assign_vector(ivl_statement_t net) value pushed. */ fprintf(vvp_out, " %%cvt/vr %u;\n", wid); - } else if (ivl_expr_value(rval) == IVL_VT_STRING) { - /* Special case: string to vector casting */ - ivl_lval_t lval = ivl_stmt_lval(net, 0); - fprintf(vvp_out, " %%vpi_call %u %u \"$ivl_string_method$to_vec\", v%p_0, v%p_0 {0 0 0};\n", - ivl_file_table_index(ivl_stmt_file(net)), ivl_stmt_lineno(net), - ivl_expr_signal(rval), ivl_lval_sig(lval)); - if (slices) free(slices); - return 0; - - } else if (ivl_expr_value(rval) == IVL_VT_DARRAY) { - /* Special case: dynamic array to vector casting */ - ivl_lval_t lval = ivl_stmt_lval(net, 0); - void*rval_addr = NULL; - - /* Even more special case: function call returning dynamic array */ - if(ivl_expr_type(rval) == IVL_EX_UFUNC) { - rval_addr = ivl_scope_port(ivl_expr_def(rval), 0); - draw_ufunc_object(rval); - /* We do not need to store the result, it is going to be - converted to vector quite soon. */ - fprintf(vvp_out, " %%pop/obj 1, 0; drop the result\n"); - } else { - rval_addr = ivl_expr_signal(rval); - } - - fprintf(vvp_out, " %%vpi_call %u %u \"$ivl_darray_method$to_vec\", v%p_0, v%p_0 {0 0 0};\n", - ivl_file_table_index(ivl_stmt_file(net)), ivl_stmt_lineno(net), - rval_addr, ivl_lval_sig(lval)); - if (slices) free(slices); - return 0; - } else { unsigned wid = ivl_stmt_lwidth(net); draw_eval_vec4(rval);