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 <lars@metafoo.de>
This commit is contained in:
parent
4c8903f117
commit
b83ebf3c8e
|
|
@ -759,31 +759,8 @@ static void store_real_to_lval(ivl_lval_t lval)
|
||||||
ivl_expr_t word_ex = ivl_lval_idx(lval);
|
ivl_expr_t word_ex = ivl_lval_idx(lval);
|
||||||
int word_ix = allocate_word();
|
int word_ix = allocate_word();
|
||||||
|
|
||||||
/* If the word index is a constant, then we can write
|
draw_eval_expr_into_integer(word_ex, word_ix);
|
||||||
directly to the word and save the index calculation.
|
fprintf(vvp_out, " %%store/reala v%p, %d;\n", var, word_ix);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
clr_word(word_ix);
|
clr_word(word_ix);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue