Merge pull request #722 from larsclausen/real-array-assignment-op
tgt-vvp: Handle assignment operator on real array entries
This commit is contained in:
commit
bf4bee319d
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Check that a assignment operator on an real array entry with an immediate
|
||||||
|
// index works if it happes after a comparison that sets vvp flag 4 to 0.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
real r[1:0];
|
||||||
|
logic a = 1'b0;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
r[0] = 8.0;
|
||||||
|
if (a == 0) begin
|
||||||
|
// Make sure that this update happens, even though the compare above
|
||||||
|
// cleared set vvp flag 4
|
||||||
|
r[0] *= 2.0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (r[0] == 16.0) begin
|
||||||
|
$display("PASSED");
|
||||||
|
end else begin
|
||||||
|
$display("FAILED. Expected %f, got %f", 16.0, r[0]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Check that assignment operators on real arrays are supported.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
real r[1:0];
|
||||||
|
integer i = 1;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
// Immediate index
|
||||||
|
r[0] = 8.0;
|
||||||
|
r[0] += 1.0;
|
||||||
|
r[0] -= 2.0;
|
||||||
|
r[0] *= 3.0;
|
||||||
|
r[0] /= 7.0;
|
||||||
|
r[0]++;
|
||||||
|
r[0]--;
|
||||||
|
|
||||||
|
// Variable index
|
||||||
|
r[i] = 8.0;
|
||||||
|
r[i] += 1.0;
|
||||||
|
r[i] -= 2.0;
|
||||||
|
r[i] *= 3.0;
|
||||||
|
r[i] /= 7.0;
|
||||||
|
r[i]++;
|
||||||
|
r[i]--;
|
||||||
|
|
||||||
|
if (r[0] == 3.0 && r[1] == 3.0) begin
|
||||||
|
$display("PASSED");
|
||||||
|
end else begin
|
||||||
|
$display("FAILED. Expected %f, got %f and %f", 3.0, r[0], r[1]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Check that the assignment operator is supported for out-of-bounds indices on
|
||||||
|
// real arrays. The write should be skipped, but side effects of the right-hand
|
||||||
|
// side expression should still get evaluated.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
real a[1:0];
|
||||||
|
integer i;
|
||||||
|
real r = 0;
|
||||||
|
|
||||||
|
function real f;
|
||||||
|
r += 0.125;
|
||||||
|
return r;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
a[0] = 23.0;
|
||||||
|
a[1] = 42.0;
|
||||||
|
|
||||||
|
// Immediate out-of-bounds indices
|
||||||
|
a[-1] += f();
|
||||||
|
a[2] += f();
|
||||||
|
a['hx] += f();
|
||||||
|
|
||||||
|
// Variable out-of-bounds indices
|
||||||
|
i = -1;
|
||||||
|
a[i] += f();
|
||||||
|
i = 2;
|
||||||
|
a[i] += f();
|
||||||
|
i = 'hx;
|
||||||
|
a[i] += f();
|
||||||
|
|
||||||
|
// Check that the in-bounds elements do not get affected by out-of-bounds
|
||||||
|
// updates. Check that the left-hand side of the operator assignment gets
|
||||||
|
// evaluated.
|
||||||
|
if (a[0] == 23.0 && a[1] == 42.0 && r == 0.75) begin
|
||||||
|
$display("PASSED");
|
||||||
|
end else begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -98,8 +98,11 @@ array_unpacked_sysfunct normal,-g2005-sv ivltests
|
||||||
array_packed normal,-g2005-sv ivltests
|
array_packed normal,-g2005-sv ivltests
|
||||||
assign_op_after_cmp1 normal,-g2009 ivltests
|
assign_op_after_cmp1 normal,-g2009 ivltests
|
||||||
assign_op_after_cmp2 normal,-g2009 ivltests
|
assign_op_after_cmp2 normal,-g2009 ivltests
|
||||||
|
assign_op_after_cmp3 normal,-g2009 ivltests
|
||||||
assign_op_concat normal,-g2009 ivltests
|
assign_op_concat normal,-g2009 ivltests
|
||||||
assign_op_oob normal,-g2009 ivltests
|
assign_op_oob normal,-g2009 ivltests
|
||||||
|
assign_op_real_array normal,-g2009 ivltests
|
||||||
|
assign_op_real_array_oob normal,-g2009 ivltests
|
||||||
assign_op_type normal,-g2009 ivltests
|
assign_op_type normal,-g2009 ivltests
|
||||||
bitp1 normal,-g2005-sv ivltests
|
bitp1 normal,-g2005-sv ivltests
|
||||||
bits normal,-g2005-sv ivltests
|
bits normal,-g2005-sv ivltests
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,9 @@ array_select CE,-pallowsigned=1 ivltests
|
||||||
array_select_a CE ivltests
|
array_select_a CE ivltests
|
||||||
array_unpacked_sysfunct CE,-g2005-sv ivltests
|
array_unpacked_sysfunct CE,-g2005-sv ivltests
|
||||||
array_word_width2 CE ivltests
|
array_word_width2 CE ivltests
|
||||||
|
assign_op_after_cmp3 CE,-g2009 ivltests
|
||||||
|
assign_op_real_array CE,-g2009 ivltests
|
||||||
|
assign_op_real_array_oob CE,-g2009 ivltests
|
||||||
br1008 CE ivltests
|
br1008 CE ivltests
|
||||||
br1019 CE ivltests
|
br1019 CE ivltests
|
||||||
br_gh556 CE,-g2009 ivltests
|
br_gh556 CE,-g2009 ivltests
|
||||||
|
|
|
||||||
|
|
@ -648,8 +648,10 @@ static void get_real_from_lval(ivl_lval_t lval, struct real_lval_info*slice)
|
||||||
it to select the word, and pay no further heed to the
|
it to select the word, and pay no further heed to the
|
||||||
expression itself. */
|
expression itself. */
|
||||||
if (word_ix && number_is_immediate(word_ix, IMM_WID, 0)) {
|
if (word_ix && number_is_immediate(word_ix, IMM_WID, 0)) {
|
||||||
assert(! number_is_unknown(word_ix));
|
if (number_is_unknown(word_ix))
|
||||||
use_word = get_number_immediate(word_ix);
|
use_word = ULONG_MAX; // The largest valid index is ULONG_MAX - 1
|
||||||
|
else
|
||||||
|
use_word = get_number_immediate(word_ix);
|
||||||
word_ix = 0;
|
word_ix = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -673,7 +675,8 @@ static void get_real_from_lval(ivl_lval_t lval, struct real_lval_info*slice)
|
||||||
if (use_word < ivl_signal_array_count(sig)) {
|
if (use_word < ivl_signal_array_count(sig)) {
|
||||||
fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n",
|
fprintf(vvp_out, " %%ix/load 3, %lu, 0;\n",
|
||||||
use_word);
|
use_word);
|
||||||
fprintf(vvp_out, " %%load/reala v%p, 3;\n", sig);
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
|
fprintf(vvp_out, " %%load/ar v%p, 3;\n", sig);
|
||||||
} else {
|
} else {
|
||||||
fprintf(vvp_out, " %%pushi/real 0, 0;\n");
|
fprintf(vvp_out, " %%pushi/real 0, 0;\n");
|
||||||
}
|
}
|
||||||
|
|
@ -688,7 +691,7 @@ static void get_real_from_lval(ivl_lval_t lval, struct real_lval_info*slice)
|
||||||
|
|
||||||
draw_eval_expr_into_integer(word_ix, slice->u_.memory_word_dynamic.word_idx_reg);
|
draw_eval_expr_into_integer(word_ix, slice->u_.memory_word_dynamic.word_idx_reg);
|
||||||
fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.memory_word_dynamic.x_flag);
|
fprintf(vvp_out, " %%flag_mov %u, 4;\n", slice->u_.memory_word_dynamic.x_flag);
|
||||||
fprintf(vvp_out, " %%load/reala v%p, %d;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg);
|
fprintf(vvp_out, " %%load/ar v%p, %d;\n", sig, slice->u_.memory_word_dynamic.word_idx_reg);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -728,6 +731,7 @@ static void put_real_to_lval(ivl_lval_t lval, struct real_lval_info*slice)
|
||||||
clr_word(word_idx);
|
clr_word(word_idx);
|
||||||
} else {
|
} else {
|
||||||
fprintf(vvp_out," ; Skip this slice write to v%p [%lu]\n", sig, slice->u_.memory_word_static.use_word);
|
fprintf(vvp_out," ; Skip this slice write to v%p [%lu]\n", sig, slice->u_.memory_word_static.use_word);
|
||||||
|
fprintf(vvp_out," %%pop/real 1;\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue