Merge pull request #715 from larsclausen/vvp-load-store-skip

tgt-vvp: Fix incorrect load or store operation skip
This commit is contained in:
Stephen Williams 2022-05-21 09:17:38 -07:00 committed by GitHub
commit 6176f8eec3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 26 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}