From 2530041a38ed16cd5b8795616581b1299bf2470f Mon Sep 17 00:00:00 2001 From: Cary R Date: Thu, 30 Jul 2020 19:51:40 -0700 Subject: [PATCH] Add support for assign array patterns to a queue --- elab_expr.cc | 12 ++++---- tgt-vvp/stmt_assign.c | 66 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 07d8bb8ad..62b7328c1 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -202,16 +202,18 @@ NetExpr*PEAssignPattern::elaborate_expr(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { // Special case: If this is an empty pattern (i.e. '{}) and - // the expected type is a DARRAY, then convert this to a null - // handle. Internally, Icarus Verilog uses this to represent - // nil dynamic arrays. - if (parms_.size() == 0 && ntype->base_type()==IVL_VT_DARRAY) { + // the expected type is a DARRAY or QUEUE, then convert this + // to a null handle. Internally, Icarus Verilog uses this to + // represent nil dynamic arrays. + if (parms_.size() == 0 && (ntype->base_type()==IVL_VT_DARRAY || + ntype->base_type()==IVL_VT_QUEUE)) { NetENull*tmp = new NetENull; tmp->set_line(*this); return tmp; } - if (ntype->base_type()==IVL_VT_DARRAY) + if (ntype->base_type()==IVL_VT_DARRAY || + ntype->base_type()==IVL_VT_QUEUE) return elaborate_expr_darray_(des, scope, ntype, flags); cerr << get_fileline() << ": sorry: I don't know how to elaborate " diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index bbba82d3b..5fde4ba29 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -1045,6 +1045,50 @@ static int show_stmt_assign_sig_darray(ivl_statement_t net) return errors; } +/* + * This function handles the special case that we assign an array + * pattern to a queue. Handle this by assigning each element. + * The array pattern will have a fixed size. + */ +static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval, + ivl_type_t element_type, int max_idx) +{ + int errors = 0; + unsigned idx; + assert(ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN); + for (idx = 0 ; idx < ivl_expr_parms(rval) ; idx += 1) { + switch (ivl_type_base(element_type)) { + case IVL_VT_BOOL: + case IVL_VT_LOGIC: + draw_eval_vec4(ivl_expr_parm(rval,idx)); + fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); + fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %d, %u;\n", var, max_idx, + width_of_packed_type(element_type)); + break; + + case IVL_VT_REAL: + draw_eval_real(ivl_expr_parm(rval,idx)); + fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); + fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, max_idx); + break; + + case IVL_VT_STRING: + draw_eval_string(ivl_expr_parm(rval,idx)); + fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); + fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, max_idx); + break; + + default: + fprintf(vvp_out, "; ERROR: show_stmt_assign_queue_pattern: " + "type_base=%d not implemented\n", ivl_type_base(element_type)); + errors += 1; + break; + } + } + + return errors; +} + static int show_stmt_assign_sig_queue(ivl_statement_t net) { int errors = 0; @@ -1076,21 +1120,27 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net) /* The %store/dar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); - fprintf(vvp_out, " %%store/qdar/r v%p_0, %u;\n", var, idx); + fprintf(vvp_out, " %%store/qdar/r v%p_0, %d;\n", var, idx); } else if (mux && ivl_type_base(element_type)==IVL_VT_STRING) { draw_eval_string(rval); /* The %store/dar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); - fprintf(vvp_out, " %%store/qdar/str v%p_0, %u;\n", var, idx); + fprintf(vvp_out, " %%store/qdar/str v%p_0, %d;\n", var, idx); } else if (mux) { // What is left must be some form of vector draw_eval_vec4(rval); resize_vec4_wid(rval, ivl_stmt_lwidth(net)); /* The %store/dar expects the array index to be in index register 3. */ draw_eval_expr_into_integer(mux, 3); - fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %u, %u;\n", var, idx, + fprintf(vvp_out, " %%store/qdar/vec4 v%p_0, %d, %u;\n", var, idx, width_of_packed_type(element_type)); + } else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) { + /* There is no l-value mux, but the r-value is an array + pattern. This is a special case of an assignment to + elements of the l-value. */ + fprintf(vvp_out, " %%delete/obj v%p_0;\n", var); + errors += show_stmt_assign_queue_pattern(var, rval, element_type, idx); } else { fprintf(stderr, "Sorry: I don't know how to handle expr_type=%d " "being assigned to a queue.\n", ivl_expr_type(rval)); @@ -1099,18 +1149,10 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net) errors += 1; } clr_word(idx); -// FIXME +// FIXME: This is probably needed to assign from an actual array. #if 0 static int show_stmt_assign_sig_darray(ivl_statement_t net) { - - - } else if (ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN) { - /* There is no l-value mux, but the r-value is an array - pattern. This is a special case of an assignment to - elements of the l-value. */ - errors += show_stmt_assign_darray_pattern(net); - } else { /* There is no l-value mux, so this must be an assignment to the array as a whole. Evaluate the