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.
This commit is contained in:
parent
1aa22735ce
commit
c066e2d15c
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue