From 199ed39abef153c69434112b7868766bf37725e8 Mon Sep 17 00:00:00 2001 From: Cary R Date: Sun, 2 Aug 2020 23:34:52 -0700 Subject: [PATCH] Report when the array pattern is larger than the maximum queue size --- tgt-vvp/stmt_assign.c | 23 +++++++++++++++++++++-- vvp/codes.h | 1 + vvp/compile.cc | 1 + vvp/vthread.cc | 20 ++++++++++++++++++++ vvp/vvp_darray.cc | 21 +++++++++++++++++++++ vvp/vvp_darray.h | 4 ++++ 6 files changed, 68 insertions(+), 2 deletions(-) diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index 5fde4ba29..c31528019 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -1055,8 +1055,19 @@ static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval, { int errors = 0; unsigned idx; + unsigned max_size; + unsigned max_elems; assert(ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN); - for (idx = 0 ; idx < ivl_expr_parms(rval) ; idx += 1) { + max_size = ivl_signal_array_count(var); + max_elems = ivl_expr_parms(rval); + if ((max_size != 0) && (max_elems > max_size)) { + fprintf(stderr, "Warning: Array pattern assignment has more elements " + "(%u) than bounded queue '%s' supports (%u).\n" + " Only using first %u elements.\n", + max_elems, ivl_signal_basename(var), max_size, max_size); + max_elems = max_size; + } + for (idx = 0 ; idx < max_elems ; idx += 1) { switch (ivl_type_base(element_type)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: @@ -1086,6 +1097,15 @@ static int show_stmt_assign_queue_pattern(ivl_signal_t var, ivl_expr_t rval, } } + if ((max_size == 0) || (max_elems < max_size)) { + int del_idx = allocate_word(); + assert(del_idx >= 0); + /* Save the first queue element to delete. */ + fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", del_idx, max_elems); + fprintf(vvp_out, " %%delete/tail v%p_0, %u;\n", var, del_idx); + clr_word(del_idx); + } + return errors; } @@ -1139,7 +1159,6 @@ static int show_stmt_assign_sig_queue(ivl_statement_t net) /* 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 " diff --git a/vvp/codes.h b/vvp/codes.h index a1a71b9a7..b715019d4 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -101,6 +101,7 @@ extern bool of_DELAY(vthread_t thr, vvp_code_t code); extern bool of_DELAYX(vthread_t thr, vvp_code_t code); extern bool of_DELETE_ELEM(vthread_t thr, vvp_code_t code); extern bool of_DELETE_OBJ(vthread_t thr, vvp_code_t code); +extern bool of_DELETE_TAIL(vthread_t thr, vvp_code_t code); extern bool of_DISABLE(vthread_t thr, vvp_code_t code); extern bool of_DISABLE_FORK(vthread_t thr, vvp_code_t code); extern bool of_DIV(vthread_t thr, vvp_code_t code); diff --git a/vvp/compile.cc b/vvp/compile.cc index a89312d88..e07d1ae48 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -153,6 +153,7 @@ static const struct opcode_table_s opcode_table[] = { { "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%delete/elem",of_DELETE_ELEM,1,{OA_FUNC_PTR,OA_NONE,OA_NONE} }, { "%delete/obj",of_DELETE_OBJ,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, + { "%delete/tail",of_DELETE_TAIL,2,{OA_FUNC_PTR,OA_BIT1,OA_NONE} }, { "%disable", of_DISABLE, 1, {OA_VPI_PTR,OA_NONE, OA_NONE} }, { "%disable/fork",of_DISABLE_FORK,0,{OA_NONE,OA_NONE, OA_NONE} }, { "%div", of_DIV, 0, {OA_NONE, OA_NONE, OA_NONE} }, diff --git a/vvp/vthread.cc b/vvp/vthread.cc index c2a3cddf2..6446ccb4b 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -2468,6 +2468,26 @@ bool of_DELETE_OBJ(vthread_t thr, vvp_code_t cp) return true; } +/* %delete/tail