From 7fe2ddda0bb2b16d4e769125fc258e8e670507c7 Mon Sep 17 00:00:00 2001 From: mjoekhan Date: Tue, 28 Apr 2026 22:17:13 +0500 Subject: [PATCH] VVP: array-pattern object values for class queue properties Support IVL_EX_ARRAY_PATTERN in object evaluation for queue-typed class properties: build an empty queue and append pattern elements, matching darray array-pattern object handling. Fix vec4 stack use so %queue/append_word/v is not double-popped. Update class queue locator regression to use direct c.q = '{...} assignment. Made-with: Cursor --- .../ivltests/sv_class_queue_prop_locators.v | 10 +-- tgt-vvp/eval_object.c | 63 ++++++++++++++----- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/ivtest/ivltests/sv_class_queue_prop_locators.v b/ivtest/ivltests/sv_class_queue_prop_locators.v index 6c91355fc..193988d1c 100644 --- a/ivtest/ivltests/sv_class_queue_prop_locators.v +++ b/ivtest/ivltests/sv_class_queue_prop_locators.v @@ -15,15 +15,7 @@ module test; initial begin c = new; - c.q.push_back(4); - c.q.push_back(7); - c.q.push_back(2); - c.q.push_back(5); - c.q.push_back(7); - c.q.push_back(1); - c.q.push_back(6); - c.q.push_back(3); - c.q.push_back(1); + c.q = '{4, 7, 2, 5, 7, 1, 6, 3, 1}; r = c.q.find() with (item > 3); `check(r.size, 5); diff --git a/tgt-vvp/eval_object.c b/tgt-vvp/eval_object.c index 7b7a9b3ed..0d121c147 100644 --- a/tgt-vvp/eval_object.c +++ b/tgt-vvp/eval_object.c @@ -173,35 +173,62 @@ static int eval_darray_new(ivl_expr_t ex) return errors; } -/* Build a dynamic-array object value from an array pattern expression. */ -static int eval_darray_pattern_object(ivl_expr_t ex) +/* Build a queue/dynamic-array object value from an array pattern expression. */ +static int eval_array_pattern_object(ivl_expr_t ex) { int errors = 0; ivl_type_t net_type = ivl_expr_net_type(ex); - if (!net_type || ivl_type_base(net_type) != IVL_VT_DARRAY) + if (!net_type) + return 1; + ivl_variable_type_t base_type = ivl_type_base(net_type); + if (base_type != IVL_VT_DARRAY && base_type != IVL_VT_QUEUE) return 1; ivl_type_t element_type = ivl_type_element(net_type); if (!element_type) return 1; - unsigned size_reg = allocate_word(); - fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", size_reg, ivl_expr_parms(ex)); - fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); - darray_new(element_type, size_reg); + unsigned max_elems = ivl_expr_parms(ex); + if (base_type == IVL_VT_QUEUE) { + unsigned max_size = ivl_type_queue_max(net_type); + if (max_size != 0 && max_elems > max_size) { + fprintf(stderr, "%s:%u: Warning: Array pattern assignment has more " + "elements (%u) than bounded queue supports (%u).\n" + " Only using first %u elements.\n", + ivl_expr_file(ex), ivl_expr_lineno(ex), max_elems, max_size, max_size); + max_elems = max_size; + } + fprintf(vvp_out, " %%queue/new_empty/v;\n"); + } else { + unsigned size_reg = allocate_word(); + fprintf(vvp_out, " %%ix/load %u, %u, 0;\n", size_reg, max_elems); + fprintf(vvp_out, " %%flag_set/imm 4, 0;\n"); + darray_new(element_type, size_reg); + } switch (ivl_type_base(element_type)) { case IVL_VT_BOOL: case IVL_VT_LOGIC: - for (unsigned idx = 0; idx < ivl_expr_parms(ex); idx += 1) { + for (unsigned idx = 0; idx < max_elems; idx += 1) { draw_eval_vec4(ivl_expr_parm(ex, idx)); - fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); - fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n"); - fprintf(vvp_out, " %%pop/vec4 1;\n"); + if (base_type == IVL_VT_QUEUE) { + fprintf(vvp_out, " %%queue/append_word/v %u;\n", + ivl_type_packed_width(element_type)); + } else { + fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); + fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n"); + fprintf(vvp_out, " %%pop/vec4 1;\n"); + } } break; case IVL_VT_REAL: - for (unsigned idx = 0; idx < ivl_expr_parms(ex); idx += 1) { + for (unsigned idx = 0; idx < max_elems; idx += 1) { + if (base_type == IVL_VT_QUEUE) { + fprintf(vvp_out, "; ERROR: eval_array_pattern_object: queue real " + "element type not implemented\n"); + errors += 1; + break; + } draw_eval_real(ivl_expr_parm(ex, idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%set/dar/obj/real 3;\n"); @@ -209,7 +236,13 @@ static int eval_darray_pattern_object(ivl_expr_t ex) } break; case IVL_VT_STRING: - for (unsigned idx = 0; idx < ivl_expr_parms(ex); idx += 1) { + for (unsigned idx = 0; idx < max_elems; idx += 1) { + if (base_type == IVL_VT_QUEUE) { + fprintf(vvp_out, "; ERROR: eval_array_pattern_object: queue string " + "element type not implemented\n"); + errors += 1; + break; + } draw_eval_string(ivl_expr_parm(ex, idx)); fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx); fprintf(vvp_out, " %%set/dar/obj/str 3;\n"); @@ -217,7 +250,7 @@ static int eval_darray_pattern_object(ivl_expr_t ex) } break; default: - fprintf(vvp_out, "; ERROR: eval_darray_pattern_object: unsupported " + fprintf(vvp_out, "; ERROR: eval_array_pattern_object: unsupported " "element type %d\n", ivl_type_base(element_type)); errors += 1; break; @@ -823,7 +856,7 @@ int draw_eval_object(ivl_expr_t ex) return eval_object_ufunc(ex); case IVL_EX_ARRAY_PATTERN: - return eval_darray_pattern_object(ex); + return eval_array_pattern_object(ex); case IVL_EX_SFUNC: /* Queue locator `with` may report IVL_VT_DARRAY in ivl; handle by name. */