Merge pull request #720 from larsclausen/vvp-assign-op-oob
tgt-vvp: Fix out-of-bounds compressed assignment to arrays
This commit is contained in:
commit
8fb38d7046
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Check that the assignment operator is supported for out-of-bounds indices.
|
||||||
|
// The write should be skipped, but side effects of the right-hand side
|
||||||
|
// expression should still get evaluated.
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
// Check that wider than 32 works
|
||||||
|
logic [39:0] a[1:0];
|
||||||
|
integer i;
|
||||||
|
logic [39:0] j = 0;
|
||||||
|
|
||||||
|
function logic [39:0] f;
|
||||||
|
j++;
|
||||||
|
return j;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
a[0] = 23;
|
||||||
|
a[1] = 42;
|
||||||
|
|
||||||
|
// 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 && a[1] == 42 && j == 6) begin
|
||||||
|
$display("PASSED");
|
||||||
|
end else begin
|
||||||
|
$display("FAILED");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -99,6 +99,7 @@ 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_concat normal,-g2009 ivltests
|
assign_op_concat normal,-g2009 ivltests
|
||||||
|
assign_op_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
|
||||||
|
|
|
||||||
|
|
@ -792,6 +792,7 @@ writemem-invalid RE ivltests gold=writemem-invalid-vlog95.gold
|
||||||
|
|
||||||
# For Verilog 95 signed is supported as an option (-pallowsigned=1).
|
# For Verilog 95 signed is supported as an option (-pallowsigned=1).
|
||||||
array6 normal,-pallowsigned=1 ivltests
|
array6 normal,-pallowsigned=1 ivltests
|
||||||
|
assign_op_oob normal,-g2009,-pallowsigned=1 ivltests
|
||||||
assign_op_type normal,-g2009,-pallowsigned=1 ivltests
|
assign_op_type normal,-g2009,-pallowsigned=1 ivltests
|
||||||
bitp1 normal,-g2009,-pallowsigned=1 ivltests
|
bitp1 normal,-g2009,-pallowsigned=1 ivltests
|
||||||
bits normal,-g2009,-pallowsigned=1 ivltests
|
bits normal,-g2009,-pallowsigned=1 ivltests
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
# include <limits.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These functions handle the blocking assignment. Use the %set
|
* These functions handle the blocking assignment. Use the %set
|
||||||
|
|
@ -101,8 +102,10 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,8 +167,12 @@ static void get_vec_from_lval_slice(ivl_lval_t lval, struct vec_slice_info*slice
|
||||||
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
fprintf(vvp_out, " %%flag_set/imm 4, 0;\n");
|
||||||
fprintf(vvp_out, " %%load/vec4a v%p, 3;\n", sig);
|
fprintf(vvp_out, " %%load/vec4a v%p, 3;\n", sig);
|
||||||
} else {
|
} else {
|
||||||
assert(wid <= 32);
|
if (wid <= 32) {
|
||||||
fprintf(vvp_out, " %%pushi/vec4 4294967295, 4294967295, %u;\n", wid);
|
fprintf(vvp_out, " %%pushi/vec4 4294967295, 4294967295, %u;\n", wid);
|
||||||
|
} else {
|
||||||
|
fprintf(vvp_out, " %%pushi/vec4 4294967295, 4294967295, 32;\n");
|
||||||
|
fprintf(vvp_out, " %%pad/s %u;\n", wid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ivl_signal_dimensions(sig) > 0 && word_ix != 0) {
|
} else if (ivl_signal_dimensions(sig) > 0 && word_ix != 0) {
|
||||||
|
|
@ -321,6 +328,7 @@ static void put_vec_to_lval_slice(ivl_lval_t lval, struct vec_slice_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/vec4 1;\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue