Merge pull request #715 from larsclausen/vvp-load-store-skip
tgt-vvp: Fix incorrect load or store operation skip
This commit is contained in:
commit
6176f8eec3
|
|
@ -0,0 +1,24 @@
|
|||
// Check that a assignment operator on an integer array entry with an immediate
|
||||
// index works if it happes after a comparison that sets vvp flag 4 to 0.
|
||||
|
||||
module test;
|
||||
|
||||
logic [7:0] x[10];
|
||||
logic a = 1'b0;
|
||||
|
||||
initial begin
|
||||
x[0] = 10;
|
||||
if (a == 0) begin
|
||||
// Make sure that this update happens, even though the compare above
|
||||
// cleared set vvp flag 4
|
||||
x[0] += 1;
|
||||
end
|
||||
|
||||
if (x[0] == 11) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED. Expected 11, got %0d", x[0]);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Check that a assignment operator on a dynamic part select of an vector works
|
||||
// if it happes after a comparison that sets vvp flag 4 to 0.
|
||||
|
||||
module test;
|
||||
|
||||
logic [7:0] a = 8'h0;
|
||||
|
||||
initial begin
|
||||
if (a == 0) begin
|
||||
// Make sure that this update happens, even though the compare above
|
||||
// cleared set vvp flag 4
|
||||
a[a+:1] += 1;
|
||||
end
|
||||
|
||||
if (a == 1) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED. Expected 1, got %0d", a);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Check that a store to am entry of real typed array with an immediate index
|
||||
// works if it happes after a comparison that sets vvp flag 4 to 0.
|
||||
|
||||
module test;
|
||||
|
||||
integer a = 0;
|
||||
real r[1:0];
|
||||
|
||||
initial begin
|
||||
if (a == 0) begin
|
||||
// Make sure that this store happens, even though the compare above
|
||||
// cleared set vvp flag 4
|
||||
r[0] = 1.23;
|
||||
end
|
||||
|
||||
if (r[0] == 1.23) begin
|
||||
$display("PASSED");
|
||||
end else begin
|
||||
$display("FAILED. Expected %f, got %f", 1.23, r[0]);
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
@ -96,6 +96,8 @@ array_size normal,-g2005-sv ivltests # test [size] arrays
|
|||
array_string normal,-g2009 ivltests
|
||||
array_unpacked_sysfunct normal,-g2005-sv ivltests
|
||||
array_packed normal,-g2005-sv ivltests
|
||||
assign_op_after_cmp1 normal,-g2009 ivltests
|
||||
assign_op_after_cmp2 normal,-g2009 ivltests
|
||||
assign_op_concat normal,-g2009 ivltests
|
||||
assign_op_type normal,-g2009 ivltests
|
||||
bitp1 normal,-g2005-sv ivltests
|
||||
|
|
|
|||
|
|
@ -1464,6 +1464,7 @@ real9 normal ivltests
|
|||
real10 normal ivltests
|
||||
real11 normal ivltests
|
||||
real_array_multi_dim normal ivltests
|
||||
real_array_store_after_cmp normal ivltests
|
||||
real_assign_deassign normal ivltests
|
||||
real_concat_invalid2 CE ivltests
|
||||
real_delay normal,-gspecify ivltests gold=real_delay.gold
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ pr3592746 CE ivltests
|
|||
real_array CE ivltests
|
||||
real_array_nb CE,-pallowsigned=1 ivltests
|
||||
real_array_multi_dim CE,-pallowsigned=1 ivltests
|
||||
real_array_store_after_cmp CE ivltests
|
||||
scan-invalid CE ivltests
|
||||
sel_rval_bit_ob CE ivltests
|
||||
sel_rval_part_ob CE ivltests
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
@ -161,6 +161,7 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
|
|||
if (use_word < ivl_signal_array_count(sig)) {
|
||||
fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n",
|
||||
use_word);
|
||||
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||
fprintf(vvp_out, " %%load/vec4a v%p, 3;\n", sig);
|
||||
} else {
|
||||
assert(wid <= 32);
|
||||
|
|
@ -759,31 +760,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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue