From b83ebf3c8ecaf00c41359fe2ecef21af29864494 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 1 Jan 2022 10:46:56 +0100 Subject: [PATCH] tgt-vvp: Fix store skip on real typed array entries When assigning a value to a real typed array entry the vvp `%store/reala` instruction. This instruction will skip the store if the vvp flag 4 is set. This is to handle the case where the index is undefined. When the index into the array is an immediate value the flag 4 is not cleared. If a previous instruction set flag 4 the store will be skipped. E.g. for the following r[0] will remain 0.0 since the assignment to it is skipped. ``` integer a = 0; real r[1:0]; if (a == 0) begin r[0] = 1.23; end ``` Fix this by using the `draw_eval_expr_into_integer()` helper function to evaluate the index into a word register. The function correctly handles all the special cases. Signed-off-by: Lars-Peter Clausen --- tgt-vvp/stmt_assign.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index ac604db73..65ccc831c 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -759,31 +759,8 @@ static void store_real_to_lval(ivl_lval_t lval) ivl_expr_t word_ex = ivl_lval_idx(lval); int word_ix = allocate_word(); - /* If the word index is a constant, then we can write - directly to the word and save the index calculation. - Out-of-bounds and undefined indices are converted to - a canonical index of 'bx during elaboration, and we - don't try to optimise that case. */ - if (word_ex && number_is_immediate(word_ex, IMM_WID, 0) && - !number_is_unknown(word_ex)) { - unsigned long use_word = get_number_immediate(word_ex); - assert(use_word < ivl_signal_array_count(var)); - fprintf(vvp_out, " %%ix/load %d, %lu, 0;\n", - word_ix, use_word); - fprintf(vvp_out, " %%store/reala v%p, %d;\n", - var, word_ix); - - } else { - unsigned do_store = transient_id++; - unsigned end_store = transient_id++; - draw_eval_expr_into_integer(word_ex, word_ix); - fprintf(vvp_out, " %%jmp/0 t_%u, 4;\n", do_store); - fprintf(vvp_out, " %%pop/real 1;\n"); - fprintf(vvp_out, " %%jmp t_%u;\n", end_store); - fprintf(vvp_out, "t_%u ;\n", do_store); - fprintf(vvp_out, " %%store/reala v%p, %d;\n", var, word_ix); - fprintf(vvp_out, "t_%u ;\n", end_store); - } + draw_eval_expr_into_integer(word_ex, word_ix); + fprintf(vvp_out, " %%store/reala v%p, %d;\n", var, word_ix); clr_word(word_ix); }