From e263d5b2687c44eab3b50b7a43fdc637a23ac9d6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 1 Jan 2022 10:45:52 +0100 Subject: [PATCH] tgt-vvp: Fix store skip for assignment operator on dynamic part select The operator assignment on dynamic part selects uses the `%store/vec4` instruction to store the value. This instruction will skip the assignment if flag 4 is set. This is for handling the case where the index is undefined. Since the left hand side of the assignment is an arbitrary expression it can change the flag. The implementation handles this by making a copy of the flag and restoring it before executing the `%store/vec4` instruction. The flag is set by the `%ix/vec4` instruction when loading the index register. But the copy of the flag is made before that and just picks up the flag that was stored by previous expressions. This can cause the store to be skipped when it shouldn't. E.g. in the following code the increment will be skipped. Flag 4 is used from the `a == 0` comparison, rather than from computing the part select index. ``` int a = 0; if (a == 0) begin a[a+:2] += 1; end $display(a); // Will print 0, should print 1 ``` Fix this by moving the copy of the flag after the `%ix/vec4` instruction. Signed-off-by: Lars-Peter Clausen --- tgt-vvp/stmt_assign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgt-vvp/stmt_assign.c b/tgt-vvp/stmt_assign.c index 754722646..e240fd619 100644 --- a/tgt-vvp/stmt_assign.c +++ b/tgt-vvp/stmt_assign.c @@ -147,9 +147,9 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice fprintf(vvp_out, " %%load/vec4 v%p_%lu;\n", sig, use_word); draw_eval_vec4(part_off_ex); - fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.part_select_dynamic.x_flag); fprintf(vvp_out, " %%dup/vec4;\n"); fprintf(vvp_out, " %%ix/vec4 %d;\n", slice->u_.part_select_dynamic.word_idx_reg); + fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.part_select_dynamic.x_flag); fprintf(vvp_out, " %%part/u %u;\n", wid); } else if (ivl_signal_dimensions(sig) > 0 && word_ix == 0) {